perl,libxml,xpath:如何通过此示例.xml文件中的属性获取元素

时间:2011-10-04 16:39:08

标签: perl xpath libxml2

我希望您的帮助如下:

给出.xml文件:

<network>
    <netelement>
            <node pwd="KOR-ASBG" func="describe_SBG_TGC">
                    <collection category="IMT" dir="Stream_statistics"></collection>
                                    </node>
    </netelement>
    <netelement>
            <node pwd="ADR-ASBG" func="describe_SBG_TGC">
                    <collection category="IMT" dir="Stream_statistics"></collection>
                    <collection category="IMT" dir="Proxy_registrar_statistics_ACCESS"></collection>
            </node>
    </netelement></network>

我想要做的是获取具有属性“KOR-ASBG”的元素,例如, 但只使用XPath。

我写了以下Perl代码:

#!/usr/bin/perl         -w

use             strict ;
use             warnings ;
use             XML::LibXML ;
use             Data::Dump qw(dump) ;


my $dump = "/some_path/_NETELEMENT_.xml" ;
my $parser = new XML::LibXML ; my $doc ;
eval{ $doc = $parser->parse_file($dump) ; } ;
if( !$doc ) { print "failed to parse $dump" ; next ; }
my $root = $doc->getDocumentElement ;

my $_demo = $root->find('/network/netelement/node[@pwd="KOR-ASBG"]') ;
print dump($_demo)."\n" ;

但是,它被显示出来的是:

bless([bless(do{\(my $o = 155172440)}, "XML::LibXML::Element")], "XML::LibXML::NodeList")

所以问题是,如何使用XPath获取包含“pwd”属性(等于“KOR-ASBG”)的XML元素?

谢谢:)

PS。我也尝试过:

my @_demo = $root->findnodes('/network/netelement/node[@pwd="KOR-ASBG"]') ;
print dump(@_demo)."\n" ;

它显示的是:

bless(do{\(my $o = 179552448)}, "XML::LibXML::Element")

3 个答案:

答案 0 :(得分:4)

技术上可能有多个匹配的元素,这就是返回结果集而不是单个节点的原因。你可以用

my ($ele) = $root->findnodes('/network/netelement/node[@pwd="KOR-ASBG"]');

这会将第一场比赛放入$ ele。

答案 1 :(得分:2)

你的翻斗车对象不是骗你的;你得到一个节点列表。要访问它,您可以迭代它或只访问第一个节点:

print $_demo->get_node(0)->toString()

当然,一旦获得实际节点,所有DOM方法都可用:

print $_demo->get_node(0)->getAttribute('func');

答案 2 :(得分:2)

你所看到的是他们在Perl中称之为“不透明的对象”。它不是哈希,而是包中的一组词汇哈希的关键,它包含所有实例的字段。它是Perl实现具有安全性的对象的方式。获取信息的唯一方法是调用他们的get访问者。

了解如何处理这些问题的方法是注意bless的第二个参数并查看:

http://search.cpan.org/perldoc?<name-of-package>

或者在您的情况下:http://search.cpan.org/perldoc?XML::LibXML::NodeList
http://search.cpan.org/perldoc?XML::LibXML::Element

现在,我并不建议在所有情况下使用它,但如果您注意到,NodeList对象是一个受祝福的数组引用。所以你可以访问 last 节点,如下所示:

my $nodes      = $root->find('/network/netelement/node[@pwd="KOR-ASBG"]');
my $first_node = $nodes->[0];
my $last_node  = $nodes->[-1];

当然,通过祝福数组或重载运算符或tie来使列表实现像数组一样运行通常是有意义的。因此,在这种情况下,我认为这不是太大的违反封装。