Хорошо, извините, что потребовалось некоторое время, чтобы вернуться к этому - легко пропустить обновления вопросов.
В любом случае, учитывая, что ваш скрипт выглядит как «собрать XML, проверить определенные ключи», я искренне думаю, что у нас может быть проблема с XY. Почему вы пытаетесь проверить свой XML, если вместо этого вы можете просто разложить его и выполнить поиск «по ключу»?
use strict;
use warnings;
use XML::Twig;
my %pos_lookup;
sub extract_measType {
my ( $twig, $meastype ) = @_;
my $pos = $meastype->att('pos');
$pos_lookup{$pos} = $meastype->text;
}
my $twig = XML::Twig->new(
'pretty_print' => 'indented_a',
'twig_handlers' => { 'measType' => \&extract_measType }
);
$twig->parse( \*DATA );
foreach my $element ( $twig->root->get_xpath('measData/measInfo/measValue') )
{
my $ldn = $element->att('measObjLdn');
print "Data for: $ldn\n";
foreach my $reading ( $element->children('r') ) {
my $pos = $reading->att('pos');
print "\t", $pos_lookup{$pos}, ":", $reading->text, "\n";
}
}
__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<measCollecFile>
<fileHeader fileFormatVersion="32.435 V10.0" dnPrefix="DC=ericsson.se,g3SubNetwork=Sweden">
<fileSender localDn="ManagedElement=1,Chassis=1"/>
<measCollec beginTime="2015-06-08T05:06:58Z"/>
</fileHeader>
<measData>
<managedElement localDn="ManagedElement=1,Chassis=1"/>
<measInfo measInfoId="schema_profile_1">
<granPeriod duration="PT60S" endTime="2015-06-08T05:06:58Z"/>
<repPeriod duration="PT60S"/>
<measType pos="1">inOctets</measType>
<measType pos="2">inPackets</measType>
<measType pos="3">mcastInOctets</measType>
<measType pos="4">mcastInPackets</measType>
<measType pos="5">mcastOutOctets</measType>
<measType pos="6">mcastOutPackets</measType>
<measType pos="7">meteringClassCounter</measType>
<measType pos="8">meteringPolicyName</measType>
<measType pos="9">outOctets</measType>
<measType pos="10">outPackets</measType>
<measType pos="11">policingClassCounter</measType>
<measValue
measObjLdn="ManagedElement=1,Chassis=1,Slot=1,Eth1GbCard=1,Ethernet1GBPort=1">
<r pos="1">337060</r>
<r pos="2">5616</r>
<r pos="3">0</r>
<r pos="4">0</r>
<r pos="5">0</r>
<r pos="6">0</r>
<r pos="7">(N/A)</r>
<r pos="8">(N/A)</r>
<r pos="9">1176</r>
<r pos="10">28</r>
<r pos="11">(N/A)</r>
</measValue>
<measValue
measObjLdn="ManagedElement=1,Chassis=1,Slot=1,Eth1GbCard=1,Ethernet1GBPort=2">
<r pos="1">1300</r>
<r pos="2">20</r>
<r pos="3">0</r>
<r pos="4">0</r>
<r pos="5">0</r>
<r pos="6">0</r>
<r pos="7">(N/A)</r>
<r pos="8">(N/A)</r>
<r pos="9">336936</r>
<r pos="10">5624</r>
<r pos="11">(N/A)</r>
</measValue>
</measInfo>
</measData>
<fileFooter>
<measCollec endTime="2015-06-08T05:06:58Z"/>
</fileFooter>
</measCollecFile>
Теперь, если вы действительно хотите проверить наличие определенных вещей, я бы предложил поиск «get_xpath»:
my %to_check = (
'/measCollecFile/measData/measInfo/measType[@pos="1"]' => 'inOctets',
'/measCollecFile/measData/measInfo/granPeriod' => '',
'/measCollecFile/fileFooter/measCollec' => '',
'/some/bogus/value' => "value",
);
foreach my $xpath ( keys %to_check ) {
my $node = $twig->root->get_xpath( $xpath, 0 );
my $value = "";
if ($node) { $value = $node->text; }
print $xpath, " => ", $value;
if ( $node and $value eq $to_check{$xpath} ) { print " OK\n"; }
else { print " ERROR\n"; }
}
Извините, я не воспроизвел вашу вещь полностью, но, надеюсь, это иллюстрирует идею? Я не думаю, что вам нужно делать столь же исчерпывающую проверку.
person
Sobrique
schedule
25.06.2015
XML::Simple
. Я бы предложил использовать что-то другое, а вместо этого просто использовать выраженияxpath
. Приведите образец XML и желаемый результат, и я уверен, что кто-нибудь может привести вам работающий пример. - person Sobrique   schedule 15.06.2015