2015-06-15 3 views
1

У меня есть скрипт perl, который оценивает скрипт xml с помощью функции keys(). Мой скрипт написан таким образом, атрибуты/теги в xml не приходят в порядок. Используются ли ключи в perl, оцениваются случайно?keys function in perl

Ex:

if((keys %{$data})[0] eq 'fileFooter' and 
    (keys %{$data->{fileFooter}})[0] eq 'measCollec' and 
    (keys %{$data->{fileFooter}->{measCollec}})[0] eq 'endTime' and 
    (keys %{$data})[1] eq 'fileHeader' and 
    (keys %{$data->{fileHeader}})[0] eq 'measCollec' and 
    (keys %{$data->{fileHeader}->{measCollec}})[0] eq 'beginTime' 

Здесь атрибут fileFooter в файле XML подходит к концу, и FileHeader приходит в самом начале. В этом случае perl будет работать нормально ???

Пожалуйста, найдите сценарий в ссылке ниже: https://docs.zoho.com/writer/published.do?rid=x6jdb8effa7ba9b0140258c9b3b1fb9617386

Пожалуйста найти XML файл в ссылке ниже:

https://docs.zoho.com/writer/ropen.do?rid=x6jdbcd99dd2df097455f99fa2907a84620ee

+2

Хеши Perl неупорядочены. Вы не можете полагаться на хэш, чтобы возвращать ключи в любом конкретном порядке. – friedo

+0

См. [Почему для печати эти же ключи имеют другой порядок?] (Http://stackoverflow.com/questions/30340027/why-do-the-same-hash-keys-have-different-order-when-printing/30340150 # 30340150) –

+2

Это также выглядит как XML, анализируемый 'XML :: Simple'. Я бы предложил использовать что-то еще и просто использовать выражения 'xpath'. Процитировать образец XML и желаемый результат, и я уверен, что кто-то может дать вам пример, который работает. – Sobrique

ответ

2

Хэши не хранить ключи в надежном порядке. Это характер хэшей, либо используйте функцию сортировки, либо используйте массив. См: http://perldoc.perl.org/functions/keys.html

0

Один из способов думать об этом стоит помнить, что вы получаете доступ к «ценности» в массиве упорядоченных элементов в структуре данных (поэтому вы используете $array[2], @array[1,2,3] или $array_ref->[3]). С хешем вы получаете доступ к «значениям» по их соответствующим ключам, которые могут быть в любом порядке, потому что вы получаете доступ к ним «неупорядоченным» способом.

См. Why do hash keys have different order when printing? и другие сообщения, связанные с "Связанные" боковой панели для более подробного обсуждения.

+1

Привет всем, Спасибо всем за ваши ценные комментарии. – Amar

2

Мне кажется, что вы пытаетесь увидеть, существуют ли ключи; если да, то попробуйте:

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} 
) { 

или, если у вас есть no autovivification; набор,

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

или сделать явным то, что no autovivification; делает для вас:

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

Привет @ikegami, Ive приложил свой скрипт и xml-файл в вопрос сейчас. Не могли бы вы проверить, сообщите мне, вышесказанного достаточно, чтобы изменить сценарий? – Amar

+0

@ Амар, а почему бы вам не рассказать нам, если у вас все еще проблема? – ikegami

+0

@ ikegami: Извините, человек. Я не знаю, что много хорошего в Perl, чтобы писать и тестировать. :/Кроме того, мне нужно немного настроить, как Linux, чтобы запустить этот скрипт, который будет бесплатным завтра. Я просто хочу, чтобы мой код был готов, так что я могу запустить и проверить его, как только я получу настройку! – Amar

0

Ключи будут храниться в по-видимому, случайный (но не по-настоящему случайный) порядок. Функции keys и values обещают вернуть элементы в одном порядке каждый раз, но только при вызове того же хэша. Другой хеш - даже если ключи одинаковы - может возвращать ключи в совершенно ином порядке. Изменение хеша может также изменить порядок клавиш.

+0

Пожалуйста, найдите файл xml ниже: https://docs.zoho.com/writer/published.do?rid=x6jdbcd99dd2df097455f99fa2907a84620ee – Amar

1

Да. Поскольку хеши по определению неупорядочены, функция ключей будет казаться «случайным образом оцениваться».

Было бы лучше проанализировать ваш xml в массиве refs.

Вы не можете рассчитывать на то, что хеш будет отображаться в том же порядке, что и время от времени.

0

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"; } 
} 

К сожалению, я не воспроизведен всю свою вещь, но, надеюсь, это иллюстрирует идею? Я не думаю, что вам нужно сделать достаточно исчерпывающее подтверждение.