2

スキーマに対してファイルをロードして検証しようとしているPerlスクリプトの例があります。それらはさまざまなノードに問い合わせます。

#!/usr/bin/env perl
use strict;
use warnings;
use XML::LibXML;

my $filename = 'source.xml';
my $xml_schema = XML::LibXML::Schema->new(location=>'library.xsd');
my $parser = XML::LibXML->new ();
my $doc = $parser->parse_file ($filename);

eval {
    $xml_schema->validate ($doc);
};

if ($@) {
    print "File failed validation: $@" if $@;
}

eval {
    print "Here\n";
    foreach my $book ($doc->findnodes('/library/book')) {
        my $title = $book->findnodes('./title');
        print $title->to_literal(), "\n";

    }
};

if ($@) {
    print "Problem parsing data : $@\n";
}

残念ながら、XML ファイルは正常に検証されていますが、$book アイテムが見つからないため、何も出力されません。

XML ファイルからスキーマを削除し、PL ファイルから検証を削除すると、問題なく動作します。

デフォルトの名前空間を使用しています。デフォルトの名前空間 (xmlns:lib="http://libs.domain.com") を使用しないように変更し、XML ファイル内のすべての項目の前に lib を付け、XPath 式を変更して名前空間のプレフィックス (/lib: library/lib:book) その後、再びファイルを動作させます。

なんで?そして私は何が欠けていますか?

XML:

<?xml version="1.0" encoding="utf-8"?>
<library xmlns="http://lib.domain.com" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://lib.domain.com .\library.xsd">
    <book>
        <title>Perl Best Practices</title>
        <author>Damian Conway</author>
        <isbn>0596001738</isbn>
        <pages>542</pages>
        <image src="http://www.oreilly.com/catalog/covers/perlbp.s.gif" width="145" height="190"/>
    </book>
    <book>
        <title>Perl Cookbook, Second Edition</title>
        <author>Tom Christiansen</author>
        <author>Nathan Torkington</author>
        <isbn>0596003137</isbn>
        <pages>964</pages>
        <image src="http://www.oreilly.com/catalog/covers/perlckbk2.s.gif" width="145" height="190"/>
    </book>
    <book>
        <title>Guitar for Dummies</title>
        <author>Mark Phillips</author>
        <author>John Chappell</author>
        <isbn>076455106X</isbn>
        <pages>392</pages>
        <image src="http://media.wiley.com/product_data/coverImage/6X/07645510/076455106X.jpg" width="100" height="125"/>
    </book>
</library>

XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://lib.domain.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://lib.domain.com">
    <xs:attributeGroup name="imagegroup">
        <xs:attribute name="src" type="xs:string"/>
        <xs:attribute name="width" type="xs:integer"/>
        <xs:attribute name="height" type="xs:integer"/>
    </xs:attributeGroup>
    <xs:element name="library">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="book">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="title" type="xs:string"/>
                            <xs:element maxOccurs="unbounded" name="author" type="xs:string"/>
                            <xs:element name="isbn" type="xs:string"/>
                            <xs:element name="pages" type="xs:integer"/>
                            <xs:element name="image">
                                <xs:complexType>
                                    <xs:attributeGroup ref="imagegroup"/>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>
4

1 に答える 1

3

XML::LibXML ドキュメントから:

XPath に関するよくある間違いは、プレフィックスのない要素名で構成されるノード テストが、デフォルトの名前空間の要素と一致すると想定することです。この仮定は間違っています。XPath 仕様により、このようなノード テストは名前空間がない (つまり null) 要素にのみ一致します。...(以降)... ...推奨される方法は、XML::LibXML::XPathContext モジュールを使用することです

したがって、XPath の観点からは、"デフォルト" の名前空間はありません。null 以外の名前空間については、XPath で指定する必要があります。XML::LibXML::XPathContext モジュールを使用すると、XPath 式で使用する名前空間のプレフィックスを作成できます。

于 2009-03-18T16:29:31.840 に答える