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

时间:2015-07-02 19:04:59

标签: 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>

我的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提取值?我也试过了,没有运气。

1 个答案:

答案 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')