2010-01-10 14 views
5

Ich habe Probleme, Namespaces mit XML::LibXML Paket in Perl zu verstehen/zu verwenden. Ich kann auf ein Element erfolgreich zugreifen, aber kein Attribut. Ich habe den folgenden Code, der auf eine XML-Datei zugreift (http://pastebin.com/f3fb9d1d0).Wie kann ich auf Attribute und Elemente von XML :: LibXML in Perl zugreifen?

Ich versuche dann, auf ein Element namens common-name und ein Attribut namens name zuzugreifen.

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" ; 
} 

Aber nur der lateinische Name (@name) druckt aus, die gebräuchlichen deutschen Namen nicht. Was mache ich falsch und wie kann ich den gemeinsamen Namen auch ausdrucken?

Was macht der @name in diesem Fall? Ich nehme an, dass es ein Array ist, und dass Attribute in ein Array eingegeben werden sollten, da es mehr als eins geben kann, aber Elemente (wie der allgemeine Name) sollten nicht sein, weil es nur einen geben sollte?

Ich verfolge die Beispiele hier: http://www.xml.com/pub/a/2001/11/14/xml-libxml.html und hier: http://perl-xml.sourceforge.net/faq/#namespaces_xpath, und versuche, ihr Beispiel Kamel Skript mit meinem Namensraum zum Laufen zu bringen, damit die seltsame Namespace.

Antwort

6

Stellen Sie sicher, dass die XML-Datei gültig ist, und verwenden Sie dann $node->getAttribute("someAttribute"), um auf Attribute zuzugreifen.

@name ist ein Attributname. Sie würden es in findnodes() verwenden, um Elemente mit einer bestimmten Attributmenge anzugeben. Z.B. ein Pfad wie:

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

Hier ist ein einfaches/konstruiertes Beispiel:

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

Ausgang ist:

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

Dank Niels, ich meine ursprüngliche Frage falsch herum aufgestellt, Der lateinische Name (@name) druckte gut, der gebräuchliche Name nicht. Nicht sicher, ob das deine Antwort ändert. Ich habe dein Beispiel versucht, aber ich konnte nichts ausdrucken. Das Problem, das ich habe, hat mehr mit dem Namespace zu tun, denke ich. Wenn ich nicht die ersten beiden Namespace-Zeilen verwende (mit $ xpc darin) und einfach auf die Elemente wie die Beispiele hier verweisen, http://www.xml.com/pub/a/2001/11/14/xml-libxml .html dann ist alles in Ordnung, aber wenn ich den Namespace einfüge, funktioniert es nicht, irgendwie bekomme ich nicht das ElementIwant – John

+0

Ich entfernte den Namespace und balancierte die Tags in der XML-Datei, auf die du Bezug nahmst, um das Beispiel auszuführen. Ich füge den Namensraum dem Beispiel hinzu. –

+0

Ich aktualisierte Ihre XML-Datei bei Pastebin http://pastebin.com/f3fb9d1d0 –