Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XML::Simple时如何删除幻数?_Xml_Perl_Xml Parsing_Xml Simple - Fatal编程技术网

使用XML::Simple时如何删除幻数?

使用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('./

我做了一个类似这样的练习,如何计算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";
}
我的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
    /
    a.count
    其他语言中的函数转换为Perl惯用语
    标量(@a)
    如果标量上下文已经应用,则
    scalar()
    函数是可选的)

    在这种情况下,数字比较运算符
    “{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”;
    }
    
    需要注意的是,计算Perl数组长度的一种稍有不同的方法是
    $#a
    构造,它返回数组最后一个元素的索引,例如,比数组中的元素数量少1。我不知道使用这两种方法之间有任何性能差异,因此如果您发现两者可读性相同,请酌情使用它们(例如,如果您需要获取最后一个元素的索引,请使用
    $\a
    ;如果使用元素,请根据需要使用
    @a
    标量(@a)

    一个好的参考是


    正如DVK所说,确保您的XMLin选项中有
    ForceArray=>[qw/Person Hobby/]
    ,否则,如果您只有一个人或任何人只有一个嗜好,事情就不会有结果。

    如果您使用“C”样式进行循环,您只需要知道数组中的项目数。相反,您可以使用更高级的版本:
    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";
            }
        }
    }