Xml perl中的键函数

Xml perl中的键函数,xml,perl,data-structures,perl-data-structures,Xml,Perl,Data Structures,Perl Data Structures,我有一个perl脚本,它使用keys()函数计算xml脚本。我的脚本就是这样编写的,xml中的属性/标记不是按顺序排列的。这些键是否在perl中起作用,是否随机计算 例: 这里,XML文件中的fileFooter属性位于末尾,fileHEader位于开头。在这种情况下,perl可以正常工作 请在以下链接中找到脚本: 请在以下链接中找到XML文件: 哈希不能以可靠的顺序存储密钥。这是哈希的本质,可以使用sort函数,也可以使用数组。请参阅:哈希不能以可靠的顺序存储密钥。这是哈希的本质,可以使用so

我有一个perl脚本,它使用
keys()
函数计算xml脚本。我的脚本就是这样编写的,xml中的属性/标记不是按顺序排列的。这些键是否在perl中起作用,是否随机计算

例:

这里,XML文件中的fileFooter属性位于末尾,fileHEader位于开头。在这种情况下,perl可以正常工作

请在以下链接中找到脚本:

请在以下链接中找到XML文件:


哈希不能以可靠的顺序存储密钥。这是哈希的本质,可以使用sort函数,也可以使用数组。请参阅:

哈希不能以可靠的顺序存储密钥。这是哈希的本质,可以使用sort函数,也可以使用数组。请参阅:

考虑这一点的一种方法是记住,通过数据结构中的有序元素访问数组中的“值”(这就是为什么使用
$array[2]
@array[1,2,3]
$array\u ref->[3]
)。使用散列,您可以通过各自的键访问“值”,这些键可以是任意顺序的,因为您以“无序”的方式访问它们


有关详细讨论,请参见“相关的”侧栏下链接的文章和其他文章。

考虑这一点的一种方法是记住,您通过数据结构中的有序元素访问数组中的“值”(这就是为什么要使用
$array[2]
@array[1,2,3]
$array\u ref->[3]
). 使用散列,您可以通过各自的键访问“值”,这些键可以是任意顺序的,因为您以“无序”的方式访问它们


请参阅“相关的”侧边栏下链接到的其他帖子,以获得更详细的讨论。

在我看来,您似乎在尝试查看是否存在键;如果是,请尝试:

if( exists $data->{fileFooter} &&
    exists $data->{fileFooter}{measCollec} &&
    exists $data->{fileFooter}{measCollec}{endTime} &&
    exists $data->{fileHeader} &&
    exists $data->{fileHeader}{measCollec} &&
    exists $data->{fileHeader}{measCollec}{beginTime}
) {
或者,如果您没有
自动激活设置

if( exists $data->{fileFooter}{measCollec}{endTime} &&
    exists $data->{fileHeader}{measCollec}{beginTime}
) {
或者明确地做
没有自动激活的事情是否为您提供:

if ( exists ${ ${ $data->{fileFooter} || {} }{measCollec} || {} }{endTime} &&
    exists ${ ${ $data->{fileHeader} || {} }{measCollec} || {} }{beginTime}
) {

在我看来,你是想看看钥匙是否存在;如果是,请尝试:

if( exists $data->{fileFooter} &&
    exists $data->{fileFooter}{measCollec} &&
    exists $data->{fileFooter}{measCollec}{endTime} &&
    exists $data->{fileHeader} &&
    exists $data->{fileHeader}{measCollec} &&
    exists $data->{fileHeader}{measCollec}{beginTime}
) {
或者,如果您没有
自动激活设置

if( exists $data->{fileFooter}{measCollec}{endTime} &&
    exists $data->{fileHeader}{measCollec}{beginTime}
) {
或者明确地做
没有自动激活的事情是否为您提供:

if ( exists ${ ${ $data->{fileFooter} || {} }{measCollec} || {} }{endTime} &&
    exists ${ ${ $data->{fileHeader} || {} }{measCollec} || {} }{beginTime}
) {

密钥将以明显随机(但不是真正随机)的顺序存储。
函数承诺每次都以相同的顺序返回元素,但只有在对同一哈希调用时。不同的散列(即使密钥相同)可能会以完全不同的顺序返回密钥。修改散列也可能更改键的顺序。

键将以明显随机(但不是真正随机)的顺序存储。
函数承诺每次都以相同的顺序返回元素,但只有在对同一哈希调用时。不同的散列(即使密钥相同)可能会以完全不同的顺序返回密钥。修改散列也可能更改键的顺序。

是。因为散列按定义是无序的,所以keys函数似乎是“随机计算的”

最好将xml解析为数组引用


您不能指望哈希以相同的顺序一次又一次地呈现。

是。因为散列按定义是无序的,所以keys函数似乎是“随机计算的”

最好将xml解析为数组引用


您不能指望哈希会以相同的顺序一次又一次地呈现出来。

好的,很抱歉花了一段时间来讨论这个问题-很容易错过问题更新

不管怎样-鉴于您的脚本似乎是“收集XML,检查某些键”-老实说,我认为这里可能有XY问题。既然可以分解XML并进行“按键”搜索,为什么还要尝试验证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> 

对不起,我没有复制你的全部内容,但希望这能说明这个想法?我不认为你需要做一个详尽的验证

好的,很抱歉花了一段时间来讨论这个问题-很容易错过问题更新

不管怎样-鉴于您的脚本似乎是“收集XML,检查某些键”-老实说,我认为这里可能有XY问题。既然可以分解XML并进行“按键”搜索,为什么还要尝试验证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> 

对不起,我没有复制你的全部内容,但希望这能说明这个想法?我不认为你需要做一个详尽的验证

Perl哈希是无序的。您不能依赖散列以任何特定顺序返回键。请参阅,这也类似于由
XML::Simple
解析的XML。我建议使用其他方法,只使用
xpath
表达式。引用一个XML示例和期望的结果,我相信有人会给你一个有效的例子。好的,有了这些信息@Amar,我们有一个不同的问题要问。我已经发布了一个我认为是解决这个问题的更好方法的答案。但无论如何,还是值得完全打开一个新的问题。Perl哈希是无序的。您不能依赖散列以任何特定顺序返回键。请参阅,这也类似于由
XML::Simple
解析的XML。我建议使用其他方法,只使用
xpath
表达式。引用一个XML示例和期望的结果,我相信有人会给你一个有效的例子。好的,有了这些信息@Amar,我们有一个不同的问题要问。我已经发布了一个我认为是解决这个问题的更好方法的答案。但无论如何,还是值得打开一个新问题。大家好,谢谢大家的宝贵意见。大家好,谢谢大家的宝贵意见。请在下面的位置找到xml文件:请在下面的位置找到xml文件:大家好,ikegami,我现在在问题中附上了我的脚本和xml文件。请检查并让我知道,以上存在的内容足以在脚本中更改???@Amar,u