Perl, как разбирать XML файл, xpath

Я хочу проанализировать XML файл, используя Perl. Я смог сделать это с помощью модуля XML:: Simple, но теперь я хочу начать использовать модуль XML:: XPath, потому что он использует XPath. Из моих ограниченных знаний я думаю, что XPaths упростит будущий синтаксический анализ, верно? Здесь код Perl, который у меня есть до сих пор:

use strict;
use warnings;
use XML::XPath;

my $file = "data.xml";
my $path = XML::XPath->new(filename => $file);

my $name = $path->find('/category/event/@name');
print $name."\n";

Мой вопрос заключается в том, как я могу отделить каждый атрибут имени (category/event/@ name), чтобы я мог выполнять тесты для каждого значения, которое я анализирую. На данный момент я просто получаю большую строку, заполненную анализируемыми данными, тогда как я хочу несколько небольших строк, которые я могу проверить. Как я могу это сделать? Спасибо: -)

Ответ 1

Этот обзор указывает, что XML::XPath hasn не обновлялся с 2003 года и вместо этого рекомендует XML::LibXML

use 5.010;
use strict;
use warnings;
use XML::LibXML;

my $dom = XML::LibXML->new->parse_file('data.xml');
for my $node ($dom->findnodes('/category/event/@name')) {
    say $node->toString;
}

См. XML::LibXML::Parser и XML::LibXML::Node.

Ответ 2

Метод find возвращает объект XML::XPath::NodeSet, который представляет собой совокупность всех найденных узлов. Я не могу представить, что вы могли бы сделать, чтобы увидеть одну длинную строку со всеми значениями атрибутов.

Получив набор узлов, вы работаете над его содержимым с помощью таких методов, как size, get_node и get_nodelist (см. документы, которые я связал выше). get_nodelist вернет список Perl, в данном случае XML::XPath::Node::Attribute объектов, которые также имеют свои собственные методы. Эта программа должна начать работу

use strict;
use warnings;

use XML::XPath;

my $xp = XML::XPath->new(ioref => \*DATA);

my $names = $xp->find('/category/event/@name');

for my $node ($names->get_nodelist) {
  say $node->getNodeValue;
}


__DATA__
  <category name="a">
    <event name="cat1" />  
    <event name="cat2" />  
    <event name="cat3" />  
    <event name="cat4" />  
    <event name="cat5" />  
  </category>

OUTPUT

cat1
cat2
cat3
cat4
cat5