【问题标题】:Why does my XSD file fail to parse with XML::LibXML?为什么我的 XSD 文件无法使用 XML::LibXML 解析?
【发布时间】:2010-12-15 16:53:37
【问题描述】:

我正在尝试使用 LibXML::Schema Validator CPAN 模块针对架构验证 XML。在同一个脚本中,我使用XML::DOM CPAN 模块来解析 XML。我希望我的脚本采用 XML 文件针对 XSD 验证它并解析它。

当我尝试运行脚本时,在对 xsd 进行验证后,它会退出并且不解析 XML。我希望它解析有效的 XML 文件并生成 DOM 结构。如果有人可以分享一些见解,我将不胜感激。

#usr/bin/perl -w
use XML::LibXML;

my $schema = XML::LibXML::Schema->new(location =>'export.xsd');
my $parser = XML::LibXML->new;

my $xml    = 'Export.xml';
my $doc    = $parser->parse_file($xml);

eval { $schema->validate( $doc ) };
print $@ if $@;

print "$xml is valid\n";

use XML::DOM;
#use strict;

my $parser = new XML::DOM::Parser;
my $doc = $parser->parsefile ("Export.xml");

my $productOfferingnodes = $doc->getElementsByTagName("productOfferings")->item(0);
my @productOffering = $productOfferingnodes->getChildNodes();
    {
        foreach  my $productOffering(@productOffering) 
        {
            if ($productOffering->getNodeType == ELEMENT_NODE)
            {
                print $productOffering->getNodeName; 
                     }
             }
     } 

错误信息:

Schemas parser error : Failed to parse the XML resource 'export.xsd'.

【问题讨论】:

  • 你能把错误信息和一些代码贴出来吗?

标签: xml perl validation parsing


【解决方案1】:

你的代码很乱。您的脚本以旨在成为 shebang 行但不是的行开头。您在这个简短的脚本中重新定义了两个变量。您检查验证是否失败,即使失败了,您也可以愉快地继续前进。这些可能不是您的问题的原因,但它们确实使诊断问题变得更加困难。我试图重构你的代码。下面的代码通过perl -c。此外,我使用sample XML and XSD files 进行了尝试。如该页面所述,由于缺少元素,验证失败。添加缺少的信息后,验证成功并产生了预期的输出。

#!/usr/bin/env perl

use strict; use warnings;

use XML::LibXML;
use XML::DOM;

my $xml = 'Export.xml';
my $xsd = 'export.xsd';

if ( my $error = validate_xml_against_xsd($xml, $xsd) ) {
    die "Validation failed: $error\n";
}

my @offerings = get_product_offerings( $xml );
print "$_\n" for @offerings;

sub get_product_offerings {
    my ($xml) = @_;

    my $parser = XML::DOM::Parser->new;
    my $doc = $parser->parsefile($xml);

    my $nodes = $doc->getElementsByTagName("book")->item(0);

    return map {
        $_->getNodeType == ELEMENT_NODE
                         ? $_->getNodeName
                         : ()
    } $nodes->getChildNodes;
}

sub validate_xml_against_xsd {
    my ($xml, $xsd) = @_;

    my $schema = XML::LibXML::Schema->new(location => $xsd);
    my $parser = XML::LibXML->new;

    my $doc = $parser->parse_file($xml);
    eval { $schema->validate( $doc ) };

    if ( my $ex = $@ ) {
        return $ex;
    }
    return;
}

输出:

作者 标题 类型 价钱 发布日期 审查

顺便说一句,验证失败时的错误消息是信息性的:Validation failed: Element 'review': This element is not expected. Expected is (pub_date ).

【讨论】:

  • 您应该发布您的贝宝帐户。
  • @Ether 不,我应该学习如何更有效地获得代表:stackoverflow.com/questions/1604124/…
  • 是的,所以应该有一个小费罐 :) 我认为他们在第一个播客中谈到了其他网站对其他网站的影响。
  • 一个小改动,使用 #!/bin/env perl 作为 shebang,因为它更便携。
【解决方案2】:

好的,以下是一些见解:

  • 您正在打印"<xml> is valid",无论它实际上是否经过正确验证。
  • 当您检查$@ 的结果时,您有一个竞争条件。正确的做法是:

eval { blah; 1 } or do { die "Encountered error: $@"; }

您在执行验证后收到什么错误消息?也许是Can't locate XML/DOM/Parser.pm in @INC...?在调用其构造函数之前,您没有执行use XML::DOM::Parser;

如果有效,我希望它解析 xml 文件

但您还没有证明它是:您收到错误“架构解析器错误:无法解析 XML 资源 'export.xsd'。”也许这表明export.xsd 无效?如果验证失败,您不应该尝试调用 parsefile

【讨论】:

  • 架构解析器错误:无法解析 XML 资源“export.xsd”。
【解决方案3】:

看起来 export.xsd 不是有效的 XML 文件。您是否尝试使用其他工具对其进行验证?验证您是否有一个有效的 XML 文件,然后担心剩下的问题。第一要务!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多