Pregunta

Tengo un script Perl de ejemplo que estoy intentando cargar y validar un archivo contra un esquema, ellos interrogan varios nodos.

#!/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";
}

Desafortunadamente, aunque está validando bien el archivo XML, no encuentra ningún elemento $ book y, por lo tanto, no imprime nada.

Si elimino el esquema del archivo XML y la validación del archivo PL, entonces funciona bien.

Estoy usando el espacio de nombres predeterminado. Si lo cambio para que no use el espacio de nombres predeterminado (xmlns: lib = " http: //libs.domain.com" y prefijo todos los elementos en el archivo XML con lib y cambio las expresiones XPath para incluir el prefijo de espacio de nombres (/ lib : library / lib: book) y luego funciona nuevamente el archivo.

¿Por qué? y que me estoy perdiendo?

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>
¿Fue útil?

Solución

Del XML :: LibXML docs :

  

Un error común sobre XPath es   suponga que las pruebas de nodo que consisten en   un nombre de elemento sin coincidencia de prefijo   elementos en el espacio de nombres predeterminado.   Esta suposición es incorrecta: por XPath   especificación, tales pruebas de nodo pueden   solo coincide con elementos que no están en   (es decir, nulo) espacio de nombres. ...(y   más tarde) ... ... La forma recomendada es   use el XML :: LibXML :: XPathContext   módulo

Entonces, desde la perspectiva de XPath, no existe un valor predeterminado espacio de nombres ... para cualquier espacio de nombres no nulo, debe especificarlo en su XPath. El módulo XML :: LibXML :: XPathContext le permite crear un prefijo para cualquier espacio de nombres para usar en su expresión XPath.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top