开发者

Perl XML::LibXML::Schema will stop validation on first error

开发者 https://www.devze.com 2023-01-06 16:43 出处:网络
I\'m trying to use the XML::LibXML::Schema to validate a xml file against a xsd. The problem is if my xml has multiple semantic issues the validation will die on the first one and not report the other

I'm trying to use the XML::LibXML::Schema to validate a xml file against a xsd. The problem is if my xml has multiple semantic issues the validation will die on the first one and not report the others.

It finds the first error, no reference to <foobar/> bash-3.2$ ./test.pl test.xsd test.xml xmlfile <test.xml> failed validation: test.xml:14: Schemas validity error : Element 'foobar': This element is not expected.

After I remove the first error, it finds another. "ten" is not an unsigned int xmlfile <test.xml> failed validation: test.xml:11: Schemas validity error : Element 'allocation': 'ten' is not a valid value of the atomic type 'xs:unsignedInt'.

Changing "ten" to 10 fixes this issue bash-3.2$ ./test.pl test.xsd test.xml No issues found

I would like to get a report of ALL the issues on a single run. Any ideas? Should I be using another module for this? Follows my Perl script and my xsd and xml files.

Thanks for your help,

Paulo

xsd:

 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

 <!-- channel -->
  <xsd:element name="channel">
   <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="username" type="xsd:string"/>
      <xsd:element name="password" type="xsd:string"/>
    </xsd:sequence>
    <xsd:attribute name="name" use="required" type="xsd:string" />
   </xsd:complexType>
  </xsd:element>

 <!-- hotel -->
  <xsd:element name="hotel">
    <xsd:complexType>
      <xsd:sequence>
      <xsd:element name="date">
      <xsd:complexType>
        <xsd:attribute name="from" use="required" type="xsd:string" />
        <xsd:attribute name="to" use="required" type="xsd:string" />
      </xsd:complexType>
      </xsd:element>
      <xsd:element ref="room" minOccurs="1"/>
      </xsd:sequence>
      <xsd:attribute name="id" use="required" type="xsd:unsignedInt" />
    </xsd:complexType>
   </xsd:element>


 <!-- room -->
 <xsd:element name="room">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="allocation" type="xsd:unsignedInt"></xsd:element>
    </xsd:sequence>
    <xsd:attribute name="id" use="required" type="xsd:string" />
  &l开发者_JS百科t;/xsd:complexType>
 </xsd:element>

 <!-- building all together -->
 <xsd:element name="request">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element ref="channel" maxOccurs="1"/>
      <xsd:element ref="hotel" maxOccurs="1"/>
    </xsd:sequence>
    <xsd:attribute name="type" use="required" type="xsd:string" />
  </xsd:complexType>
 </xsd:element>

xml:

<?xml version="1.0" encoding="UTF-8"?>
<request type="test" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <channel name="channel">
    <username>user</username>
    <password>pass</password>
  </channel>

  <hotel id="ten">
    <date from="2009-07-07" to="2009-07-17"/>
    <room id="1">
      <allocation>ten</allocation>
    </room>
  </hotel>
</request>

perl script:

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;
#use Carp;
use vars qw( $xsd $xml $schema $parser $doc );

use XML::LibXML;


#
# MAIN
#
my $xsd = $ARGV[0];
my $xml = $ARGV[1];

$schema = XML::LibXML::Schema->new(location => $xsd);
$parser = XML::LibXML->new;
$doc    = $parser->parse_file($xml);
eval { $schema->validate($doc) };

if ( $@ ) {
warn "xmlfile <$xml> failed validation: $@" if $@; exit(1);
}
else { print "No issues found\n"; }


Try passing recover => 1 to XML::LibXML->new. It might help.

Docs from XML::LibXML::Parser...

   recover
       /parser, html, reader/

       recover from errors; possible values are 0, 1, and 2

       A true value turns on recovery mode which allows one to parse
       broken XML or HTML data. The recovery mode allows the parser to
       return the successfully parsed portion of the input document. This
       is useful for almost well-formed documents, where for example a
       closing tag is missing somewhere. Still, XML::LibXML will only
       parse until the first fatal (non-recoverable) error occurs,
       reporting recoverable parsing errors as warnings. To suppress even
       these warnings, use recover=>2.

       Note that validation is switched off automatically in recovery
       mode.


I've got contacted by the maintainer of XML::LibXML and filled this is as bug fix. Turns out you can get multiple errors reported by using the command line utility xmllint:

$ xmllint --schema test.xsd test.xml
<?xml version="1.0" encoding="UTF-8"?>
<request xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="test">
<channel name="channel">
<username>user</username>
<password>pass</password>
</channel>

<hotel id="ten">
<date from="2009-07-07" to="2009-07-17"/>
<room id="1">
<allocation>10</allocation>
</room>
</hotel>
<foobar/>
</request>
test.xml:8: element hotel: Schemas validity error : Element 'hotel', 
attribute 'id': 'ten' is not a valid value of 
the atomic type 'xs:unsignedInt'.
test.xml:14: element foobar: Schemas validity error : Element 'foobar': 
This element is not expected.
test.xml fails to validate

0

精彩评论

暂无评论...
验证码 换一张
取 消