Как я могу получить доступ к атрибутам и элементам из XML :: LibXML в Perl? - PullRequest
6 голосов
/ 11 января 2010

У меня проблемы с пониманием / использованием пространств имен с пакетом XML :: LibXML в Perl. Я могу получить доступ к элементу успешно, но не к атрибуту. У меня есть следующий код, который обращается к файлу XML (http://pastebin.com/f3fb9d1d0).

my $tree = $parser->parse_file($file); # parses the file contents into the new libXML object.
my $xpc = XML::LibXML::XPathContext->new($tree); 
$xpc->registerNs(microplateML => 'http://moleculardevices.com/microplateML');   

Затем я пытаюсь получить доступ к элементу с именем common-name и атрибуту с именем name.

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

Но распечатывается только латинское имя (@name), обычное имя - нет. Что я делаю не так, и как мне распечатать общее имя?

Что делает @name в этом случае? Я предполагаю, что это массив, и эти атрибуты должны быть помещены в массив, так как их может быть больше одного, но элементов (например, общего имени) быть не должно, потому что должен быть только один? *

Я следил за примерами здесь: http://www.xml.com/pub/a/2001/11/14/xml-libxml.html и вот: http://perl -xml.sourceforge.net / faq / # namespaces_xpath и пытаюсь заставить их примерный верблюжий скрипт работать с моим пространством имен, отсюда и странное пространство имен.

1 Ответ

7 голосов
/ 11 января 2010

Убедитесь, что ваш XML-файл корректен, затем используйте $node->getAttribute("someAttribute") для доступа к атрибутам.

@ name - это имя атрибута. Вы бы использовали его в findnodes (), чтобы указать элементы с заданным набором атрибутов. Например. путь как:

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

Вот простой / надуманный пример:

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

Вывод:

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