使用命名空间时使用 Perl 和 LibXML 获取子节点值

Bri*_*ian 5 perl libxml2

我以以下 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 提取值?我也尝试过,但没有任何运气。

ike*_*ami 4

$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)

尖端: