添加到行为异常的Perl哈希 [英] Adding to a Perl hash behaving unexpectedly

查看:58
本文介绍了添加到行为异常的Perl哈希的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过将时间标签从事件内部移动到其父内部来更改一些XML,以按时间对事件进行分组.那是...

I am trying to alter some XML to group events by time, by moving the time tag from within the event to within its parent. That is...

<schedule>
    <event>
        <time>02:00</time>
        <other_details>details</other_details>
    </event>
    <event>
        <time>02:00</time>
        <other_details>details</other_details>
    </event>
    <event>
        <time>03:00</time>
        <other_details>details</other_details>
    </event>
<schedule>

应该成为

<schedule>
    <event>
        <time>02:00</time>
        <event_details>
            <other_details>details</other_details>
        </event_details>
        <event_details>
            <other_details>details</other_details>
        </event_details>
    </event>
    <event>
        <time>03:00</time>
        <event_details>
            <other_details>details</other_details>
        </event_details>
    </event>
</schedule>

我解决此问题的方法是使用XML :: Simple将XML读取到哈希中,花点时间,然后将其用作另一个哈希的键,该哈希包含一个 event_details .代码:

The way I've approached this is using XML::Simple to read the XML into a hash, taking the time out, and using it as a key for another hash which holds an array of event_details. Code:

#!/Perl/bin/perl
#scheduleConversion.plx v1.0

use strict;
use warnings;

use XML::Simple;
use Data::Dumper;

use constant EVENTTAG   => 'event';
use constant TIMETAG    => 'event_time';
use constant DETAILSTAG => 'event_details';

if($#ARGV != 0) {
    print "Usage: First argument should be filename, optionally with path.";
}

# Get filename/path from the arguments
my $docname = shift @ARGV;

# Create a new XML parser
my $xml = new XML::Simple;
# Read in the XML data
my $XMLdata = $xml->XMLin($docname);
# New XML data to be output
my %XMLnew;
$XMLnew{&EVENTTAG} = [];

my %timeGroups;

foreach (@{$XMLdata->{&EVENTTAG}}) {
    my $time = ${$_}{&TIMETAG};
    delete ${$_}{&TIMETAG};

    # Make an array if none exists
    $timeGroups{$time} = [] unless exists($timeGroups{$time});
    # Add our details to the array
    push($timeGroups{$time}, $_);
}

foreach (%timeGroups) {
    push ($XMLnew{&EVENTTAG}, $_{&EVENTTAG});
}

#print $xml->XMLout(%XMLnew);

问题是当我尝试 print Dumper(%timeGroups); 时,它给了我这样的结果:

The issue is when I try to print Dumper(%timeGroups);, it gives me a result like this:

$VAR1 = '2015-09-10 03:59:00';
$VAR2 = [
          {
            'event_detail_1' => 'details_1',
            'event_detail_2' => 'details_2'
          }
        ];

我希望将日期作为关键,但似乎完全是一个不同的条目.我用一个单独的哈希值对此进行了测试,还创建了一个键/值对,如 $ hash {key} ='value',它给出了与上述相同的意外结果,而 $ hash = {'key'=>'value'} 给出了预期的结果.
我确定我只是缺少有关Perl哈希工作原理的信息,但这是我的理解,这两种方法应该是等效的.我整天都在脑子里打问题,我只是设法将其缩小到这个原因.

I would expect to see the date as the key, but it seems to be a different entry entirely. I tested this with a separate hash, also creating a key/value pair as $hash{key} = 'value', which gave the same unexpected result as above, while $hash = {'key' => 'value'} gave the expected result.
I'm sure I'm just missing something about how Perl hashes work, but it was my understanding both of these methods should be equivalent. I've smacked the problem with my brain all day and I've just managed to narrow it down to this cause.

推荐答案

print Dumper(%timeGroups)%timeGroups 展平为键和值的列表并传递 Dumper 的多个参数.通常,您希望传递给Dumper一个参考: print Dumper(\%timeGroups).

print Dumper(%timeGroups) is flattening %timeGroups into a list of keys and values and passing multiple arguments to Dumper. Usually you want to pass Dumper a single reference: print Dumper(\%timeGroups).

这篇关于添加到行为异常的Perl哈希的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆