我以以下 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>
Run Code Online (Sandbox Code Playgroud)
我的 XML 文件中有多个 parentNode 节点(这里只显示了一个),所以我在 parentNode 中循环。一旦我有了一个,我想在 XML 中再获得 3 个级别的属性值。我的 XML 使用名称空间,并且我已在 Perl 脚本中将该名称空间注册为“plm”。我可以在我的路径中使用名称空间来获取 parentNode 属性值。但是,当我尝试向下导航到节点“C”和拾取属性“id”时,出现以下错误:
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";
}
Run Code Online (Sandbox Code Playgroud)
如果我在子节点 ./A/B/C 上不使用命名空间,则脚本将继续执行而不会出错,但不会为 $val 分配任何值。如果我添加 plm: 前缀,则会出现命名空间错误。有谁知道我在这里做错了什么?我是否必须使用 findnodes 首先找到子节点,然后使用 findvalue 提取值?我也尝试过,但没有任何运气。
$node->findvalue('./plm:A/plm:B/plm:C/@title')
Run Code Online (Sandbox Code Playgroud)
应该
$xc->findvalue('./plm:A/plm:B/plm:C/@id', $node)
Run Code Online (Sandbox Code Playgroud)
尖端:
领导的人./都是没用的。
$node->findvalue('./@status')
$xc->findvalue('./plm:A/plm:B/plm:C/@id', $node)
Run Code Online (Sandbox Code Playgroud)
与
$node->findvalue('@status')
$xc->findvalue('plm:A/plm:B/plm:C/@id', $node)
Run Code Online (Sandbox Code Playgroud)您可以使用getAttribute来获取元素的属性,所以
$node->findvalue('@status')
Run Code Online (Sandbox Code Playgroud)
也可以使用更有效地完成
$node->getAttribute('status')
Run Code Online (Sandbox Code Playgroud)