OK, извините за то, что вы нашли время, чтобы вернуться на это - легко пропустить обновления вопросов.
В любом случае - Учитывая, что ваш скрипт, похоже, «собирает 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"; }
}
К сожалению, я не воспроизведен всю свою вещь, но, надеюсь, это иллюстрирует идею? Я не думаю, что вам нужно сделать достаточно исчерпывающее подтверждение.
Хеши Perl неупорядочены. Вы не можете полагаться на хэш, чтобы возвращать ключи в любом конкретном порядке. – friedo
См. [Почему для печати эти же ключи имеют другой порядок?] (Http://stackoverflow.com/questions/30340027/why-do-the-same-hash-keys-have-different-order-when-printing/30340150 # 30340150) –
Это также выглядит как XML, анализируемый 'XML :: Simple'. Я бы предложил использовать что-то еще и просто использовать выражения 'xpath'. Процитировать образец XML и желаемый результат, и я уверен, что кто-то может дать вам пример, который работает. – Sobrique