使用 XML::Simple 时如何删除 Magic Number?
我做了这样的练习,如何计算通过 XML::Simple 折叠到数组中的 XML 元素的数量,这样我就不必对元素的数量进行硬编码? 我计划使用代码来解析更大的 xml 文件。我不想手动计算元素。
我可以使用一些计数来替换幻数吗,有点像 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";
}
输出:
could not find ParserDetails.ini in C:/Perl/site/lib/XML/SAX
$VAR1 = {
'person' => [
{
'hobbie' => [
'bungy jumping',
'sky diving',
'knitting'
],
'last_name' => 'Bloggs',
'first_name' => 'Joe'
},
{
'hobbie' => [
'Swim',
'bike',
'run'
],
'last_name' => 'LIU',
'first_name' => 'Jack'
}
]
};
Joe Bloggs
bungy jumping
sky diving
knitting
Jack LIU
Swim
bike
run
我的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>
I did a exercise like this, how do I calculate the # of XML elements collapsed into an array by XML::Simple so I don't have to hard-code the # of elements?
I plan to use the code to parse a bigger xml file. I don't want to cout the elements by manual.
Can I use some count to replace the magic numbers, a little like person.count
or hobbie.length
etc. As I know, I can use this kind of statement in C# conveniently.
#!/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";
}
Out put:
could not find ParserDetails.ini in C:/Perl/site/lib/XML/SAX
$VAR1 = {
'person' => [
{
'hobbie' => [
'bungy jumping',
'sky diving',
'knitting'
],
'last_name' => 'Bloggs',
'first_name' => 'Joe'
},
{
'hobbie' => [
'Swim',
'bike',
'run'
],
'last_name' => 'LIU',
'first_name' => 'Jack'
}
]
};
Joe Bloggs
bungy jumping
sky diving
knitting
Jack LIU
Swim
bike
run
My Xml source file as below
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于 XML::Simple 将为您生成一个数组,因此很容易计算其长度。
例如,
$tree->{person}
是一个数组,或者更确切地说是一个数组引用(即使只有 1 个人,也可以使用 XML::Simple 的 ForceArray 选项来确保它是一个数组)。您可以通过首先将其取消引用到数组本身来获取其长度(使用
@{}
数组取消引用):@{ $tree->{person} }
然后,您在标量上下文中使用结果数组,该数组的计算结果为数组中的元素数量(换句话说,
a.lenth
/a.count 函数会转换为 Perl 习语
scalar(@a)
(如果标量上下文已适用,则scalar()
函数是可选的)。在这种情况下,数字比较运算符
“<”
将强制使用标量上下文,但如果不是这种情况,您可以使用scalar()
函数.示例:
请注意,计算 Perl 数组长度的一种稍有不同的方法是
$#a
构造,它返回数组最后一个元素的索引 - 例如,比数组中元素的数量少 1。我不知道使用这两种方法之间有任何性能差异,因此如果您发现两种方法具有相同的可读性,请酌情使用它们(例如,如果您需要获取最后一个元素的索引,请使用$#a
; 如果有 # 个元素,请根据需要使用@a
或scalar(@a)
)。一个很好的参考是 Perl Data Structures Cookbook @perldoc
Since XML::Simple will produce an array for you, it's easy to count its length.
E.g.
$tree->{person}
is an array - or rather an array reference (make sure it's one by using ForceArray option of XML::Simple even if there's only 1 person).You can get its length by first de-referencing it into an array itself (using
@{}
array de-reference):@{ $tree->{person} }
Then you use the resulting array in a scalar context which evaluates to the # of elements in the array (In other words,
a.lenth
/a.count
functions in other languages translate to Perl idiomscalar(@a)
were thescalar()
function is optional if scalar context already applies).In this case, the numeric comparison operator
"<"
will force the scalar context, but if that was not the case you could have usedscalar()
function.Example:
As a note, a somewhat different method of counting the length of a Perl array is the
$#a
construct, which returns the index of the last element of the array - e.g. 1 less than the amount of elements in the array. I'm not aware of any performance difference between using the two approaches, so if you find both equally readable, use them as appropriate (e.g. if you need to get index of the last element, use$#a
; if # of elements, use@a
orscalar(@a)
as needed).A good reference is Perl Data Structures Cookbook @perldoc
正如 DVK 所说,确保你有
ForceArray =>; [qw/Person Hobby/]
在您的 XMLin 选项中,否则如果您只有一个人或任何人只有一种爱好,事情就不会成功。and as DVK says, make sure you have
ForceArray => [qw/Person Hobby/]
in your XMLin options or else things won't work out if you only have one person or any person only has one hobby.如果您使用“C”风格的 for 循环,则只需知道数组中的项目数。相反,您可以使用更糟糕的版本:
foreach my $val ( @list )
为了更安全(并且可以说更具可读性),您可能需要检查<在尝试循环之前, /code> 具有任何
元素:You only need to know the number of items in the array if you are using the 'C' style for loop. Instead, you could use the more perlish version:
foreach my $val ( @list )
To be safer (and arguably more readable), you might want to check that a
<person>
has any<hobbie>
elements at all, before trying to loop through them: