如何从perl中的XML文件中提取具有相同名称的多个标记

时间:2013-06-05 21:08:51

标签: perl xml-parsing

我的XML文件如下所示:

<eLinkResult>
  <LinkSet>
    <DbFrom>nuccore</DbFrom>
    <IdList>
      <Id>133909243</Id>
    </IdList>
    <LinkSetDb>
      <DbTo>taxonomy</DbTo>
      <LinkName>nuccore_taxonomy</LinkName>
      <Link>
        <Id>417290</Id>
      </Link>
      <Link>
        <Id>417289</Id>
      </Link>
      <Link>
        <Id>405948</Id>
      </Link>
    </LinkSetDb>
  </LinkSet>
</eLinkResult>

我希望获取所有<Id>信息,并且我知道如果有<Id>这样的信息如何提取:

my $test="Some URL;
      my $Result = get ($test);
      my $Data = $Parser->XMLin($Result);
my $x=0;
if (exists($Data->{LinkSet}{LinkSetDb}->[0]->{Link}{Id})) {
    $TaxId=$Data->{LinkSet}{LinkSetDb}{Link}->[0]->{Id};

或只是

if (exists($Data->{LinkSet}{LinkSetDb}{Link}{Id})) {
    $TaxId=$Data->{LinkSet}{LinkSetDb}{Link}{Id};
}

但是,当我尝试使用上面的XML文件时,我得到Not a HASH reference

我也试过

foreach  (@{$Data->{LinkSet}{LinkSetDb}{Link}{Id}}) {
Print $_;
}

但是我仍然遇到错误,有没有办法可以获得所有<Id>而无需指定我想要的那个?

2 个答案:

答案 0 :(得分:2)

尝试使用解析器XML::Twig

script.pl的内容:

#!/usr/bin/env perl

use warnings;
use strict;
use XML::Twig;

my $twig = XML::Twig->new(
    twig_handlers => {
        'LinkSet/LinkSetDb/Link/Id' => sub {
            printf qq|%s\n|, $_->text_only;
        },  
    },  
)->parsefile( shift );

使用xml文件作为输入参数运行它,如:

perl script.pl xmlfile

产量:

417290
417289
405948

答案 1 :(得分:2)

XML::Simple很少是处理XML的好选择。它并不能准确地表示XML数据结构,根据我的经验,它的使用并不简单,因为它创建的Perl数据结构很难预测并且难以导航。

XML::LibXMLXML::Twig是很好的候选者,虽然XML::Twig可以用来逐个处理大型XML文件,但没有理由以这种方式使用它。

这个简短的程序使用XML::Twig来读取完整的数据结构并打印所有Id元素的文本值。

use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig->new;
$twig->parsefile('xml.xml');
print $_->text, "\n" for $twig->findnodes('//Id');

<强>输出

133909243
417290
417289
405948

<强>更新

如果您只需要Id部分数据中的LinkSetDb元素而不是IdList内部的元素,请将findnodes调用更改为$twig->findnodes('//Link/Id') }

相关问题