【问题标题】:How to extract multiple tags with same name from an XML file in perl如何从perl中的XML文件中提取多个具有相同名称的标签
【发布时间】:2013-06-01 17:50:56
【问题描述】:

我的 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>

我希望获取所有&lt;Id&gt; 信息,如果有一个&lt;Id&gt;,我知道如何提取,如下所示:

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 $_;
}

但我仍然得到一个错误,有没有一种方法可以让我获得所有 &lt;Id&gt; 而无需指定我想要哪个?

【问题讨论】:

  • 你需要遍历所有的 Link 元素,然后在循环体中获取 Id。

标签: perl xml-parsing


【解决方案1】:

尝试使用解析器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

【讨论】:

    【解决方案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
    

    更新

    如果您只想要 LinkSetDb 数据部分中的 Id 元素而不是 IdList 中的元素,则将 findnodes 调用更改为 $twig-&gt;findnodes('//Link/Id')

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-31
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 2011-09-25
      • 2019-05-29
      • 1970-01-01
      • 2020-10-06
      相关资源
      最近更新 更多