使用XML::Simple时如何删除幻数?
我做了一个类似这样的练习,如何计算XML::Simple折叠成数组的XML元素的#数,这样我就不必硬编码元素的#数了? 我计划使用该代码解析一个更大的xml文件。我不想用手工操作这些元素 我可以用一些计数来代替神奇的数字吗,有点像使用XML::Simple时如何删除幻数?,xml,perl,xml-parsing,xml-simple,Xml,Perl,Xml Parsing,Xml Simple,我做了一个类似这样的练习,如何计算XML::Simple折叠成数组的XML元素的#数,这样我就不必硬编码元素的#数了? 我计划使用该代码解析一个更大的xml文件。我不想用手工操作这些元素 我可以用一些计数来代替神奇的数字吗,有点像person.count或hobbie.length等。我知道,我可以方便地在C中使用这种语句 #!/usr/bin/perl -w use strict; use XML::Simple; use Data::Dumper; my $tree = XMLin('./
person.count
或hobbie.length
等。我知道,我可以方便地在C中使用这种语句
#!/usr/bin/perl -w
use strict;
use XML::Simple;
use Data::Dumper;
my $tree = XMLin('./t1.xml');
print Dumper($tree);
print "\n";
for (my $i = 0; $i < 2; $i++) # magic number '2'
{
print "$tree->{person}->[$i]->{first_name} $tree->{person}->[$i]->{last_name}\n";
print "\n";
for (my $j = 0; $j < 3; $j++) # magic number '3'
{
print $tree->{person}->[$i]->{hobbie}->[$j], "\n";
}
print "\n";
}
我的Xml源文件如下
<Document>
<person>
<first_name>Joe</first_name>
<last_name>Bloggs</last_name>
<hobbie>bungy jumping</hobbie>
<hobbie>sky diving</hobbie>
<hobbie>knitting</hobbie>
</person>
<person>
<first_name>Jack</first_name>
<last_name>LIU</last_name>
<hobbie>Swim</hobbie>
<hobbie>bike</hobbie>
<hobbie>run</hobbie>
</person>
</Document>
乔
布洛格斯
绑紧跳
跳伞
编织
杰克
线路接口单元
游
自行车
跑
由于XML::Simple将为您生成一个数组,因此很容易计算其长度
例如,$tree->{person}
是一个数组,或者更确切地说是一个数组引用(使用XML::Simple的ForceArray选项确保它是一个数组,即使只有一个人)
- 您可以首先将其反引用到数组本身中(使用
数组反引用):@{}
@{$tree->{person}
- 然后在标量上下文中使用生成的数组,该数组的计算结果为数组中元素的#(换句话说,
/a.lenth
其他语言中的函数转换为Perl惯用语a.count
如果标量上下文已经应用,则标量(@a)
函数是可选的) 在这种情况下,数字比较运算符scalar()
需要注意的是,计算Perl数组长度的一种稍有不同的方法是“{person}->[$i]->{first_name}$tree->{person}->[$i]->{last_name}\n”; 打印“\n”; 对于(my$j=0;$j<@{$tree->{person}->[$i]->{hobbie}};$j++){ 打印$tree->{person}->[$i]->{hobbie}->[$j],“\n”; } 打印“\n”; }
构造,它返回数组最后一个元素的索引,例如,比数组中的元素数量少1。我不知道使用这两种方法之间有任何性能差异,因此如果您发现两者可读性相同,请酌情使用它们(例如,如果您需要获取最后一个元素的索引,请使用$#a
;如果使用元素,请根据需要使用$\a
或@a
) 一个好的参考是标量(@a)
正如DVK所说,确保您的XMLin选项中有
,否则,如果您只有一个人或任何人只有一个嗜好,事情就不会有结果。如果您使用“C”样式进行循环,您只需要知道数组中的项目数。相反,您可以使用更高级的版本:ForceArray=>[qw/Person Hobby/]
为了更安全(也更具可读性),在尝试循环遍历foreach my$val(@list)
元素之前,您可能需要检查
是否包含任何
元素:foreach my $person ( @{ $tree->{person} } ) { print "$person->{first_name} $person->{last_name}\n"; if(my $hobbies = $person->{hobbie}) { foreach my $hobbie ( @$hobbies ) { print "$hobbie\n"; } } }
如果我是你,我会把你的问题从“魔法”改为“如何计算XML元素的#通过XML::Simple折叠成一个数组,这样我就不必硬编码元素的#”# Don't forget ForceArray option of XML::Simple to ensure person and hobbie are array refs for (my $i = 0; $i < scalar( @{ $tree->{person} } ); $i++) { # scalar() is optional here print "$tree->{person}->[$i]->{first_name} $tree->{person}->[$i]->{last_name}\n"; print "\n"; for (my $j = 0; $j < @{ $tree->{person}->[$i]->{hobbie} }; $j++) { print $tree->{person}->[$i]->{hobbie}->[$j], "\n"; } print "\n"; }
for my $person (@{ $tree->{person} }) { print "$person->{first_name} $person->{last_name}\n\n"; for my $hobby (@{ $person->{hobbie} }) { print $hobby, "\n"; } print "\n"; }
#!/usr/bin/perl use strict; use warnings; use XML::Simple qw(:strict XMLin); use Data::Dumper; my $tree = XMLin('./t1.xml', KeyAttr => { }, ForceArray => [ 'person', 'hobbie' ]); foreach my $person ( @{ $tree->{person} } ) { print "$person->{first_name} $person->{last_name}\n"; foreach my $hobbie ( @{ $person->{hobbie} } ) { print "$hobbie\n"; } }
foreach my $person ( @{ $tree->{person} } ) { print "$person->{first_name} $person->{last_name}\n"; if(my $hobbies = $person->{hobbie}) { foreach my $hobbie ( @$hobbies ) { print "$hobbie\n"; } } }