我有以下XML文件
<root>
<test name="test1">
<node name="node1">
</node>
<child type="" line="321" name="">
<grandChild name="WM">
....
</grandChild>
</child>
</test>
<test name="test2">
<node name="node2">
</node>
<child type="" line="123" name="">
<grandChild name="WM">
....
</grandChild>
</child>
</test>
</root>
如果条件成立,我想访问某些节点,但是我无法获得<grandChild>
个子元素。
我的Perl代码如下
my $xml = XML::LibXML::XPathContext->new();
my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs(sr => 'http://www.froglogic.com/XML2');
my $tree = $parser->parse_file($xmlFile);
my $nodes = $xml->findnodes("//sr:root/sr:test[$attribute]", $tree);
my $childTagName = 'child';
foreach my $node ( $nodes->get_nodelist ) {
my $childNodes = $node->getChildNodes();
foreach my $childNode ( $childNodes->get_nodelist ) {
if ( $childNode->getName() eq $childTagName ) {
my $newresults = $childNode->findnodes('//child');
}
}
}
当然,删除它的主要部分是为了简化我的问题。
我应该提到$attribute
是测试名称(test1,test2,....)。
请您告诉我为什么我无法在$newresults
中找到孙子,当我打印到命令控制台时,它总是空的。
答案 0 :(得分:3)
您的代码无法运行。 $attribute
来自哪里?此外,您不会在XML中显示sr
命名空间的定义,因此很难猜出问题是什么,但我的猜测是child
也属于命名空间。如果是这种情况,您也必须使用它的前缀,并使用XPath上下文来搜索它。另外,使用XPath指定条件而不是迭代子节点:
#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
use XML::LibXML;
my $tree = 'XML::LibXML'->load_xml(IO => *DATA);
my $xpc = 'XML::LibXML::XPathContext'->new($tree);
$xpc->registerNs(sr => 'http://sr');
my $attribute = '@name';
my $test_nodes = $xpc->findnodes("/sr:root/sr:test[$attribute]");
for my $test_node (@$test_nodes) {
for my $child_node ($xpc->findnodes('sr:child', $test_node)) {
my $newresults = $xpc->findnodes('sr:grandChild', $child_node);
say join ' ',
$test_node->{name},
$child_node->{line},
$_->{name}
for @$newresults;
}
}
__DATA__
<root xmlns='http://sr'>
<test name="test1">
<node name="node1">
</node>
<child type="" line="321" name="">
<grandChild name="WM">
....
</grandChild>
</child>
</test>
<test name="test2">
<node name="node2">
</node>
<child type="" line="123" name="">
<grandChild name="WM">
....
</grandChild>
</child>
</test>
</root>