【发布时间】:2014-06-06 04:49:10
【问题描述】:
我正在尝试处理项目的 XML 列表(在本例中为图像)并遍历每个项目。我不太了解 Perl 或哈希,但我找到了一些解释和示例(这里有很多)并写了一些似乎有效的东西。 XML 是一个元素列表,每个元素都包含一个唯一的“id”属性。
我正在使用 XML::Simple 中的 XMLin 来解析 XML。
当列表包含多个元素时,它会通过 'id' 进行迭代。但是好像只有一个的时候会混淆,把元素的每个属性都当作自己的值,导致运行时出错。
在使用“strict refs”时不能使用字符串(“0”)作为 HASH ref
我猜问题在于哈希键并不是唯一键,至少当只有一个条目时。所以我添加了代码来转储密钥。我还添加了一行来打印$image 在foreach 循环中的内容。在中断的情况下,print "In loop; image ID=$image\n"; 行显示In loop; image ID=Serial 由于Serial 是与id 处于同一级别的属性,我猜这是问题所在(未正确使用id 作为键) .
这是我的代码:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
my $album_data_file = $ARGV[0];
my $album_file_list = $ARGV[1];
my $do_dump_data = $ARGV[2];
my $album_data = XMLin ( $album_data_file );
my $LIST_FILE;
if ( defined $album_file_list && "$album_file_list" ne "" )
{
if ( open ( $LIST_FILE, ">", "$album_file_list" ) )
{
print "Opened file $album_file_list as $LIST_FILE\n";
}
}
if ( defined $do_dump_data && $do_dump_data eq "true" )
{
use Data::Dumper;
print "data:\n\n";
print Dumper ( $album_data );
print "\n\n\n\n";
print "keys:\n\n";
print Dumper ( keys %{$album_data->{Images}->{Image}} );
print "\n\n\n\n";
}
foreach my $image ( keys %{$album_data->{Images}->{Image}} )
{
print "In loop; image ID=$image\n";
my $ref = $album_data->{Images}->{Image}->{$image};
#
# Write to files list: file name, ID, key, size, MD5
#
print $LIST_FILE ( "$ref->{FileName}\t$image\t$ref->{Key}"
. "\t$ref->{Size}\t$ref->{MD5Sum}\n" );
}
close ( $LIST_FILE );
这是一个破坏它的示例 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<rsp stat="ok">
<method>images.get</method>
<Images>
<Image id="123" Key="xyz" Type="Album" Caption="Room 5083" FileName="MVI_2838.AVI" Format="MP4" Height="480" Keywords="China; Suite" LastUpdated="2014-04-19 11:49:45" Position="1" Serial="0" Size="116033" Width="640" Date="2014-04-19 11:46:24" Hidden="0" MD5Sum="6151e20053eeda87c688f8becae0d402" Watermark="0">
<Album id="345" Key="zzy" />
</Image>
</Images>
</rsp>
这是转储完整 $album_data 的结果:
$VAR1 = {
'method' => 'images.get',
'Images' => {
'Image' => {
'Serial' => '0',
'Format' => 'MP4',
'Keywords' => 'China; Suite',
'Type' => 'Album',
'Size' => '116033',
'MD5Sum' => '6151e20053eeda87c688f8becae0d402',
'id' => '123',
'Key' => 'xyz',
'LastUpdated' => '2014-04-19 11:49:45',
'Album' => {
'id' => '345',
'Key' => 'zzy'
},
'Position' => '1',
'Height' => '480',
'Date' => '2014-04-19 11:46:24',
'Caption' => 'Room 5083',
'FileName' => 'MVI_2838.AVI',
'Hidden' => '0',
'Width' => '640',
'Watermark' => '0',
}
},
'stat' => 'ok'
};
这是转储键 %{$album_data->{Images}->{Image}} 构造的结果:
$VAR1 = 'Serial';
$VAR2 = 'Format';
$VAR3 = 'Keywords';
$VAR5 = 'Type';
$VAR6 = 'Size';
$VAR7 = 'MD5Sum';
$VAR9 = 'id';
$VAR10 = 'Key';
$VAR11 = 'LastUpdated';
$VAR12 = 'Album';
$VAR14 = 'Position';
$VAR15 = 'Height';
$VAR16 = 'Date';
$VAR17 = 'Caption';
$VAR19 = 'FileName';
$VAR20 = 'Hidden';
$VAR23 = 'Width';
$VAR24 = 'Watermark';
$VAR27 = 'Duration';
【问题讨论】:
标签: perl hash foreach xml-parsing key