XML :: LibXML findnodes не возвращает ни одного соответствующего узла - PullRequest
0 голосов
/ 02 декабря 2011

У меня есть простой XML без пространства имен.

Я использую XML :: LibXML :: Reader для анализа XML.Когда я получаю соответствующий Элемент, я заканчиваю поиск.Как я понимаю, этот элемент имеет тип XML :: LibXML :: Element.(У меня есть определенные ограничения для продолжения работы с XML :: LibXML :: Reader)

Когда я пытаюсь использовать findnodes с xpath, это не работает.Вот код

my $libXMLPattern = XML::LibXML::Pattern->new('widget');
my $element;

my $reader = XML::LibXML::Reader->new(string => $xml);
$reader->nextElement();

while ($reader->nextPatternMatch($libXMLPattern))
{
    next if ($reader->nodeType == XML_READER_TYPE_END_ELEMENT);
    $element = $reader->copyCurrentNode(1);
        last;
}
$reader->finish();


    my $xPathExp = '//component';
    my @nodes = $element->findnodes ($xPathExp);

Вот код XML

<widget name="a" type="b">
<component type="C">
    <component type="ca"/>
    <component type="cb"/>
</component>
</widget>
<window>
...
</window>

Пожалуйста, помогите мне, что я не так делаю?

1 Ответ

1 голос
/ 03 декабря 2011
use strict;
use warnings;
use feature qw( say );

use XML::LibXML::Reader qw( XML_READER_TYPE_END_ELEMENT );

my $xml = <<'__EOI__';
<widget name="a" type="b">
  <component type="C">
    <component type="ca"/>
    <component type="cb"/>
  </component>
</widget>
__EOI__

my $libXMLPattern = XML::LibXML::Pattern->new('widget');

my $element;
my $reader = XML::LibXML::Reader->new( string => $xml );
while ($reader->nextPatternMatch($libXMLPattern)) {
   next if $reader->nodeType == XML_READER_TYPE_END_ELEMENT;
   $element = $reader->copyCurrentNode(1);
   last;
}
$reader->finish();

die if !$element;

say $_->getAttribute('type') for $element->findnodes('.//component');

Выход:

C
ca
cb

Ключ //component против .//component.

//component

- это сокращение для

/descendant:component

Wellэлемент не существует в документе, поэтому не нужно начинать с /.С другой стороны,

.//component

- это сокращение от

./descendant:component

, что означает

descendant:component

Этот путь относительно существующего узла, поэтомуможет быть обработан.

В следующий раз, пожалуйста, предоставьте минимальный и исполняемый код кода, который демонстрирует проблему.

...