为什么我的XSD文件无法用XML::LibXML解析?

为什么我的XSD文件无法用XML::LibXML解析?,xml,perl,validation,parsing,Xml,Perl,Validation,Parsing,我正在尝试使用CPAN模块根据模式验证XML。在同一个脚本中,我使用CPAN模块解析XML。我想让我的脚本获取XML文件,并根据XSD对其进行验证和解析 当我尝试运行脚本时,在根据xsd进行验证后,它将退出,并且不会解析XML。如果XML文件有效,我希望它解析XML文件并生成DOM结构。如果有人能分享一些见解,我将不胜感激 #usr/bin/perl -w use XML::LibXML; my $schema = XML::LibXML::Schema->new(location =&

我正在尝试使用CPAN模块根据模式验证XML。在同一个脚本中,我使用CPAN模块解析XML。我想让我的脚本获取XML文件,并根据XSD对其进行验证和解析

当我尝试运行脚本时,在根据xsd进行验证后,它将退出,并且不会解析XML。如果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; 
                     }
             }
     } 
错误消息:


架构分析器错误:无法解析XML资源“export.xsd”。

好的,下面是一些细节:

无论是否正确验证,您正在打印的内容都是有效的。 当您检查$@的结果时,您有一个竞争条件。正确的方法是: eval{blah;1}或do{die遇到错误:$@;}

执行验证后,您收到了什么错误消息?是不是在@INC.中找不到XML/DOM/Parser.pm。。。?您没有使用XML::DOM::Parser;在调用其构造函数之前

我想让它解析xml文件,如果它是有效的


但是您还没有证明这一点:您得到了错误模式解析器错误:未能解析XML资源“export.xsd”。也许这表明export.xsd无效?如果验证失败,则不应尝试调用parsefile。

看起来export.xsd不是有效的XML文件。您是否尝试使用其他工具验证它?确认您有一个有效的XML文件,然后担心问题的其余部分。第一件事

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

#!/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;
}
输出:

author title genre price pub_date review
顺便说一下,验证失败时的错误消息提供了信息:验证失败:元素“review”:不需要此元素。预计是发布日期。

您能发布错误消息并可能发布一些代码吗?架构解析器错误:无法解析XML资源“export.xsd”。您应该发布您的paypal帐户。@Ether不,我应该学习如何更有效地赚取销售代表:是,所以应该有一个提示罐:我想他们在第一个播客中谈到了其他网站有多糟糕/bin/env perl作为shebang,因为它更易于移植。