我有XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="MeasDataCollection.xsl"?>
<measCollecFile xmlns="">
<fileHeader fileFormatVersion="32.435 V7.2.0">
</fileHeader>
<measData>
<managedElement localDn="bs=8" swVersion="R21A"/>
<measInfo measInfoId="CORE,SIP_session_statistics">
<measType p="1">CPUUSAGE</measType>
<measType p="2">CPUMEM</measType>
<measType p="3">SYSMEM</measType>
<measValue measObjLdn="SGC.bsNo=17,networkRole=2">
<r p="1">10</r>
<r p="2">20</r>
<r p="3">30</r>
</measValue>
<measValue measObjLdn="SGC.bsNo=18,networkRole=2">
<r p="1">40</r>
<r p="2">50</r>
<r p="3">60</r>
</measValue>
</measInfo>
</measData>
</measCollecFile>
问题:
我想从40
元素中提取<r p="1">40</r>
。唯一给出的是<measType p="1">CPUUSAGE</measType>
和<measValue measObjLdn="SGC.bsNo=18,networkRole=2">
即我只知道我需要找到CPUUSAGE
的{{1}}。始终保持数据的顺序。
这是我到目前为止所尝试的内容:
bsNo=18
我的挑战是可以有许多元素,如CPUUSAGE,CPUMEM ......以及我如何在my $qry="//measInfo[measType/text() = 'CPUUSAGE']/measValue";
my @nodes= $conn->findnodes($qry);
foreach my $vnode (@nodes) {
if ($vnode->getAttribute('measObjLdn') =~ /'bsNo=18'/) {
foreach my $node ($vnode) {
foreach my $p ($node->getChildnodes) {
if (ref($p)=~'Element'){
$no=$p->textContent;
print $no;**#this prints the value of all the <r> elements**
}
}
}
}
}
元素中按顺序为给定的<r>
属性({{1)达到正确的顺序}})。
随后将该40修改为其他所需的值**
答案 0 :(得分:0)
您的Perl代码无效,因为您将属性值与'bsNo=18'
匹配,包括单引号。
如果要查找与r
节点具有相同p
属性的CPUUSAGE
元素,可以尝试使用ikegami的单个XPath表达式,如下所示:< / p>
for my $type_node ($conn->findnodes('//measInfo/measType[.="CPUUSAGE"]')) {
my $p = $type_node->getAttribute('p');
my $qry = <<"EOF";
..
/measValue[contains(concat(\@measObjLdn, ','), 'bsNo=18,')]
/r[\@p='$p']
EOF
for my $r_node ($type_node->findnodes($qry)) {
print $r_node->textContent, "\n";
}
}
首先遍历内容为measType
的所有CPUUSAGE
个节点,获取p
属性,然后找到所有相应的r
个节点。这种方法应该比单个XPath查询更有效。
要按位置查找r
节点并修改其内容,请尝试:
for my $type_node ($conn->findnodes('//measInfo/measType[.="CPUUSAGE"]')) {
my $pos = $type_node->findvalue('count(preceding-sibling::measType) + 1');
my $qry = <<"EOF";
..
/measValue[contains(concat(\@measObjLdn, ','), 'bsNo=18,')]
/r[$pos]
EOF
for my $r_node ($type_node->findnodes($qry)) {
$r_node->removeChildNodes;
$r_node->appendText('50');
}
}
print $conn->toString;