Question

J'ai un exemple de script Perl que je tente de charger et de valider un fichier par rapport à un schéma. Ils interrogent différents nœuds.

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

Malheureusement, bien que le fichier XML soit validé correctement, il ne trouve pas d’éléments $ book et n’imprime donc rien.

Si je supprime le schéma du fichier XML et la validation du fichier PL, cela fonctionne correctement.

J'utilise l'espace de noms par défaut. Si je le modifie pour ne pas utiliser l'espace de nom par défaut (xmlns: lib = " http: //libs.domain.com"), préfixez tous les éléments du fichier XML avec lib et modifiez les expressions XPath pour inclure le préfixe d'espace de nom (/ lib : library / lib: book) puis le fichier fonctionne à nouveau.

Pourquoi? et qu'est-ce qui me manque?

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>
Était-ce utile?

La solution

D'après les documents XML :: LibXML :

  

Une erreur courante à propos de XPath est de   supposons que les tests de nœud consistant en   un nom d'élément sans correspondance de préfixe   éléments dans l'espace de noms par défaut.   Cette hypothèse est fausse - par XPath   spécification, ces tests de nœud peuvent   correspond seulement aux éléments qui ne sont en aucun   (c'est-à-dire null) un espace de noms. ...(et   plus tard) ... ... La façon recommandée est de   utilisez le XML :: LibXML :: XPathContext   module

Donc, du point de vue de XPath, il n'y a pas de "défaut". namespace ... pour tout espace de noms non NULL, vous devez le spécifier dans votre XPath. Le module XML :: LibXML :: XPathContext vous permet de créer un préfixe pour tout espace de nom à utiliser dans votre expression XPath.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top