OK, sorry for taking a while to come back on this - it's easy to miss question updates.
Anyway - Given your script seems to be 'gather XML, check for certain keys' - I honestly think we may have an XY problem here. Why are you trying to validate your XML when you could instead just decompose it and do a 'by key' search?
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>
Now, if you really want to check for the presence of particular things, I'd suggest a 'get_xpath' search:
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"; }
}
Sorry, I haven't reproduced your whole thing, but hopefully this illustrates the idea? I don't think you need to do quite as exhaustive a validation though.