XML :: LibXML findnodes不返回任何匹配的节点

时间:2011-12-02 13:22:55

标签: perl libxml2

我有一个没有命名空间的简单XML。

我使用XML :: LibXML :: Reader来解析XML。当我得到匹配的元素时,我完成了搜索。据我所知,这个元素是XML :: LibXML :: Element类型。 (我有一定的限制继续使用XML :: LibXML :: Reader)

当我尝试使用带有xpath的findnodes时,它无效。 这是代码

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 个答案:

答案 0 :(得分:1)

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 vs .//component

//component

的缩写
/descendant:component

嗯,该元素在文档中不存在,因此没有/开始。另一方面,

.//component

的缩写
./descendant:component

这是

的长期
descendant:component

该路径相对于现有节点,因此可以进行处理。

下次,请提供演示此问题的 minimal runnable 代码。