XML:仅获取节点的某些子节点

时间:2018-11-28 09:25:22

标签: xml perl xml-parsing

我想遍历以下xml中的两个会话作为两个单独的节点:

abc.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<resource>    
<session>
     <parameter name="QWS" value="N1"/> 
     <parameter name="AQC" value="Y2"/>
     <parameter name="VDF" value="301"/>
     <parameter name="VTT" value="X2"/>
     <parameter name="HRR" value="Y2"/>
 </session>
 <session>
    <parameter name="ABC" value="N"/> 
     <parameter name="XYZ" value="Y"/>
     <parameter name="GHI" value="30"/>
     <parameter name="DEF" value="X"/>
     <parameter name="QQW" value="Y"/>  
    </session> 
</resource>

但是,当我运行此代码时,它两次遍历两个会话:

#!/usr/bin/perl
use warnings;
use strict;
use XML::LibXML;

my $filename = 'E:/perl_files/abc.xml';
my $dom = XML::LibXML->load_xml(location => $filename);

foreach my $session ($dom->findnodes('//session'))
{
    print "In SESSION \n";
    foreach my $parameter ($session->findnodes('//parameter')) {
        my $name= $parameter->getAttribute('name');
        my $value= $parameter->getAttribute('value');
        print "Tag in session is $name with value $value\n";
    }
    print "END OF SESSION\n";   
}

把这个输出留给我:

In SESSION
Tag in session is QWS with value N1
Tag in session is AQC with value Y2
Tag in session is VDF with value 301
Tag in session is VTT with value X2
Tag in session is HRR with value Y2
Tag in session is ABC with value N
Tag in session is XYZ with value Y
Tag in session is GHI with value 30
Tag in session is DEF with value X
Tag in session is QQW with value Y
END OF SESSION
In SESSION
Tag in session is QWS with value N1
Tag in session is AQC with value Y2
Tag in session is VDF with value 301
Tag in session is VTT with value X2
Tag in session is HRR with value Y2
Tag in session is ABC with value N
Tag in session is XYZ with value Y
Tag in session is GHI with value 30
Tag in session is DEF with value X
Tag in session is QQW with value Y
END OF SESSION

我希望输出为

In SESSION
Tag in session is QWS with value N1
Tag in session is AQC with value Y2
Tag in session is VDF with value 301
Tag in session is VTT with value X2
Tag in session is HRR with value Y2
END OF SESSION
In SESSION
Tag in session is ABC with value N
Tag in session is XYZ with value Y
Tag in session is GHI with value 30
Tag in session is DEF with value X
Tag in session is QQW with value Y
END OF SESSION

我正在使用XML :: LibXML。 我可以进行哪些更改以使每次仅获得一个会话的子节点? 我看到了使用childNodes()的答案,但是它将返回一个列表,并且我不想使用grep查找特定的节点。

2 个答案:

答案 0 :(得分:4)

//parameter到处搜索parameter,您只需要在session下(即当前节点下)进行搜索:

    foreach my $parameter ($session->findnodes('.//parameter')) {

答案 1 :(得分:3)

//parameter

的缩写
/descendant::parameter

表示名为/的根节点(parameter)的后代,但是您想获取上下文节点的后代。为此,您想要

descendant::parameter

也可以写为

.//parameter

问题是,parameter是会话的孩子,所以您真正想要的只是

child::parameter

也可以写为

parameter

最终代码:

#!/usr/bin/perl
use warnings;
use strict;
use XML::LibXML;

my $filename = 'E:/perl_files/abc.xml';
my $dom = XML::LibXML->load_xml(location => $filename);

foreach my $session ($dom->findnodes('/resource/session'))         # <---
{
    print "In SESSION \n";
    foreach my $parameter ($session->findnodes('parameter')) {     # <---
        my $name= $parameter->getAttribute('name');
        my $value= $parameter->getAttribute('value');
        print "Tag in session is $name with value $value\n";
    }
    print "END OF SESSION\n";   
}