2010-01-10 4 views
5

J'ai de la difficulté à comprendre/utiliser des espaces de noms avec le paquet XML::LibXML dans Perl. Je peux accéder à un élément avec succès, mais pas un attribut. J'ai le code suivant qui accède à un fichier XML (http://pastebin.com/f3fb9d1d0). Ensuite, j'essaie d'accéder à un élément appelé common-name et à un attribut appelé name.Comment accéder aux attributs et éléments de XML :: LibXML en Perl?

foreach my $camelid ($xpc->findnodes('//microplateML:species')) { 
    my $latin_name = $camelid->findvalue('@name'); 
    my $common_name = $camelid->findvalue('common-name'); 
    print "$latin_name, $common_name" ; 
} 

Mais seul le latin-nom (@name) est impression-, le nom commun n'est pas. Qu'est-ce que je fais de mal et comment puis-je obtenir le nom commun à imprimer aussi?

Que fait le @name dans ce cas? Je suppose que c'est un tableau, et que les attributs devraient être mis dans un tableau car il peut y en avoir plus d'un, mais les éléments (comme le nom commun) ne devraient pas être parce qu'il devrait y en avoir un seul?

J'ai suivi les exemples ici: http://www.xml.com/pub/a/2001/11/14/xml-libxml.html et ici: http://perl-xml.sourceforge.net/faq/#namespaces_xpath, et essayer d'obtenir leur script de chameau exemple travailler avec mon espace de noms, d'où l'espace de noms bizarre.

Répondre

6

Assurez-vous que votre fichier XML est valide, puis utilisez $node->getAttribute("someAttribute") pour accéder aux attributs.

@nom est un nom d'attribut. Vous l'utiliseriez dans findnodes() pour spécifier des éléments avec un ensemble d'attributs donné. Par exemple. un chemin comme:

//camelids/species[@name="Camelus bactrianus"]/

Voici un exemple simple/artificiel:

#!/usr/bin/perl -w 
use XML::LibXML; 

my $parser = XML::LibXML->new(); 
my $doc = $parser->parse_file('/Users/castle/Desktop/animal.xml'); 

my $xc = XML::LibXML::XPathContext->new($doc->documentElement() ); 
$xc->registerNs('ns', 'http://moleculardevices.com/microplateML'); 

my @n = $xc->findnodes('//ns:species'); 
foreach $nod (@n) { 
    print "A: ".$nod->getAttribute("name")."\n"; 

    my @c = $xc->findnodes("./ns:common-name", $nod); 
    foreach $cod (@c) { 
     print "B: ".$cod->nodeName; 
     print " = "; 
     print $cod->getFirstChild()->getData()."\n"; 
    } 
} 

sortie est:

perl ./xmltest.pl 
A: Camelus bactrianus 
B: common-name = Bactrian Camel 
+0

Merci Niels, je suis arrivé à ma question d'origine dans le mauvais sens, le nom latin (@name) était bien imprimé, le nom commun ne l'était pas. Je ne sais pas si cela change votre réponse. J'ai essayé votre exemple mais je n'ai pas pu imprimer quoi que ce soit. Le problème que j'ai est plus lié à l'espace de noms que je pense. Si je n'utilise pas les deux premières lignes d'espace de noms (avec $ xpc en eux) et juste référence les éléments comme les exemples ici http://www.xml.com/pub/a/2001/11/14/xml-libxml .html alors tout va bien, mais quand j'inclus l'espace de noms, ça ne marche pas, je ne reçois pas l'élément. – John

+0

J'ai enlevé l'espace de noms et équilibré les balises dans le fichier XML que vous utilisiez pour faire tourner l'exemple. Je vais ajouter l'espace de noms à l'exemple. –

+0

J'ai mis à jour votre fichier XML à pastebin http://pastebin.com/f3fb9d1d0 –

Questions connexes