infinitloop
infinitloop

Reputation: 3011

Is there a way to quickly validate data using Perl and XML::Simple

My XML file looks like this:

<A>
 <file>data1</file>
 <path>data2</path>
</A>

<B>
  <file>data3</file>
  <path>data4</path>
</B>

So I read the data from a log file, parse it and get tags like A, B, file and path. Right now I use a for loop to iterate over each outer tag, and then compare against each sub tag to see if the data exists in the XML file.

$data = $xml->XMLin("xmlfile");

foreach $e ( $data->{$outerTag} ) # outertag could be A, B
{
 if( $e->{file} eq $fname ) { do_something } else { return 0; }
 if( $e->{path} eq $pname ) { do_something } else { return 0; }
}

Is there a way whereby I don't have to use the for loop.? Say I could do something like this (I am making this up):

if( $data->{$outerTag}->{$fname} ) { do_something } else { return 0; }

Upvotes: 0

Views: 377

Answers (3)

Mark O&#39;Connor
Mark O&#39;Connor

Reputation: 77991

Most of the standards based XML schema validators are Java or Python based nowadays :-(

I would suggest using xmllint and you could also look at XMLLint perl module.

Example

$ xmllint --noout --schema schema.xml data.xml
data.xml validates

data.xml

<data>
  <A>
    <file>data1</file>
    <path>data2</path>
  </A>
  <B>
    <file>data3</file>
    <path>data4</path>
  </B>
</data>

schema.xml

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0">
  <xsd:element name="data" type="dataType"/>
  <xsd:complexType name="dataType">
    <xsd:sequence>
      <xsd:element name="A" type="AType"/>
      <xsd:element name="B" type="BType"/>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:complexType name="BType">
    <xsd:sequence>
      <xsd:element name="file" type="xsd:string"/>
      <xsd:element name="path" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:complexType name="AType">
    <xsd:sequence>
      <xsd:element name="file" type="xsd:string"/>
      <xsd:element name="path" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

Note:

Upvotes: 1

Borodin
Borodin

Reputation: 126742

As long as XML::Simple has built a rational structure for your data you can write

if ( $data->{$outerTag}{file} eq $fname ) { ... }

but, depending on what you want to do with the data, you may well be better off using a better XML parser, like XML::LibXML.

Upvotes: 2

Zaid
Zaid

Reputation: 37146

Perl doesn't have an official "XML parser"; there are a plethora of options to choose from, some better than others depending on the application.

You may want to read up about XML validation using schemas. In a nutshell, you need to write up a schema for what you deem as valid XML, then validate the XML file against it.

Upvotes: 2

Related Questions