我有一个没有命名空间的简单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>
请帮我解决我的错误?
答案 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 代码。