我有以下XML作为示例:
<root xmlns="http://www.plmxml.org/Schemas/PLMXMLSchema" >
<parentNode status="Good">
<A>
<B>
<C id="123" >C Node Value Here</C>
</B>
</A>
</parentNode>
</root>
我的XML文件中有多个parentNode节点(这里只显示了一个),所以我在parentNode中循环播放。有了一个,我想在XML中获得更多级别的属性值。我的XML使用名称空间,我在我的Perl脚本中注册了名称空间为&#34; plm&#34;。我可以使用路径中的名称空间来获取parentNode属性值。但是,当我尝试向下导航到节点&#34; C&#34;和拾取属性&#34; id&#34;,我收到以下错误:
XPath错误:未定义的命名空间前缀 错误:xmlXPathCompiledEval:评估失败
我正在使用以下Perl脚本。
use XML::LibXML;
use XML::LibXML::XPathContext;
my $filename = "namespaceissue.xml";
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($filename);
my $xc = XML::LibXML::XPathContext->new( $doc->documentElement() );
$xc->registerNs('plm', 'http://www.plmxml.org/Schemas/PLMXMLSchema');
foreach my $node ($xc->findnodes('/plm:root/plm:parentNode')) {
my $status = $node->findvalue('./@status');
print "Status = $status\n";
my $val = $node->findvalue('./plm:A/plm:B/plm:C/@title');
print "Value = $val\n";
}
如果我在子节点./A/B/C上没有使用命名空间,则脚本继续没有错误,但没有为$ val分配值。如果我添加plm:前缀,我会得到命名空间错误。有谁知道我在做错了什么?我是否必须使用findnodes首先找到子节点,然后使用findvalue提取值?我也试过了,没有运气。
答案 0 :(得分:2)
$node->findvalue('./plm:A/plm:B/plm:C/@title')
应该是
$xc->findvalue('./plm:A/plm:B/plm:C/@id', $node)
提示:
那些领先的./
没用。
$node->findvalue('./@status')
$xc->findvalue('./plm:A/plm:B/plm:C/@id', $node)
与
相同$node->findvalue('@status')
$xc->findvalue('plm:A/plm:B/plm:C/@id', $node)
您可以使用getAttribute
获取元素的属性,因此
$node->findvalue('@status')
也可以使用
更有效地完成$node->getAttribute('status')