2009-03-18 3 views
2

У меня есть пример скрипта Perl, который я пытаюсь загрузить и проверить файл по схеме, они опросили различные узлы.Perl, LibXML и Schemas

#!/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 ([email protected]) { 
    print "File failed validation: [email protected]" if [email protected]; 
} 

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

    } 
}; 

if ([email protected]) { 
    print "Problem parsing data : [email protected]\n"; 
} 

К сожалению, несмотря на то, что он корректно проверяет XML-файл, он не находит никаких предметов в $ book и, следовательно, ничего не распечатывает.

Если я удалю схему из файла XML и проверку из файла PL, тогда она отлично работает.

Я использую пространство имен по умолчанию. Если я изменю его, чтобы не использовать пространство имен по умолчанию (xmlns: lib = "http://libs.domain.com" и префикс всех элементов в XML-файле с помощью lib и изменить выражения XPath для включения префикса пространства имен (/ lib: библиотека/библиотека: книги), то он снова работает файл

Почему и что мне не хватает

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> 

ответ

3

от XML::LibXML docs:

Частая ошибка о XPath является предположить, что тесты узлов, состоящих из имя элемента, без префикса матча элементов в пространстве имен по умолчанию. Это предположение неверно: спецификация XPath , такие тесты узлов могут соответствовать только элементам, которые не имеют пространства имен (т. Е. Null). ... (и позже) ... ... Рекомендуемый способ заключается в использовать модуль XML::LibXML::XPathContext

Таким образом, с точки зрения XPath, нет пространства имен «по умолчанию» ... для любое ненулевое пространство имен, вы должны указать его в своем XPath. Модуль XML :: LibXML :: XPathContext позволяет создавать префикс для любого пространства имен, которое будет использоваться в вашем выражении XPath.

Смежные вопросы