0

我有一个 xml 文件,我想将入口节点的 id 与反应节点的 id 进行比较,如果与下面的示例相同,我想访问反应的所有信息(基板 id 和产品 id)。我有两个产品 ID,这段代码给出了第一个这是 XML 文件

<?xml version="1.0"?>
<!DOCTYPE pathway SYSTEM "http://www.kegg.jp/kegg/xml/KGML_v0.7.1_.dtd">
<!-- Creation date: May 31, 2012 14:53:24 +0900 (GMT+09:00) -->
<pathway name="path:ko00010" org="ko" number="00010" >
    <entry id="13">
    </entry>
    <entry id="37" >
    </entry>
    <reaction id="13" name="rn:R01070" type="reversible">
      <substrate id="105" name="cpd:C05378"/>
      <product id="132" name="cpd:C00118"/>
      <product id="89" name="cpd:C00111"/>
    </reaction>
</pathway>

这是我的代码

use strict;
use warnings;
use XML::Simple;

my $xml = new XML::Simple;
my $data = $xml->XMLin("file.xml");
foreach my $entry (keys %{$data->{entry}}) {
    foreach my $reaction (keys %{$data->{reaction}}) {
    if ($data->{reaction}->{id} eq $data->{entry}->{$entry}->{id} ){
        print "substrate:::$data->{reaction}->{substrate}->{id}\n";
        print "product:::$data->{reaction}->{product}->{id}\n";
    }
    }
}
4

1 回答 1

1

XML::Simple 绝非简单。它自己的文档不鼓励进一步使用该模块。

你可能得到的数据结构(谁知道?)在我的系统上:

{
  entry    => { 13 => {}, 37 => {} },
  name     => "path:ko00010",
  number   => "00010",
  org      => "ko",
  reaction => {
                id => 13,
                name => "rn:R01070",
                product => { "cpd:C00111" => { id => 89 }, "cpd:C00118" => { id => 132 } },
                substrate => { id => 105, name => "cpd:C05378" },
                type => "reversible",
              },
}

当您不确定是否正确访问数据结构时,检查数据结构总是好的。一种方法是use Data::Dumper; print Dumper $data.

您可能会注意到id. entry此外,products 没有 ID 字段,而是使用name属性作为名称。*叹气* – 这种“聪明”就是您不应该使用 XML::Simple 的原因。


使用适当的解析器(如XML::LibXML. 然后我们可以使用 XPath 来选择我们想要的节点:

use XML::LibXML;
use feature 'say';

my $data = XML::LibXML->load_xml(location => "test.xml");
my $query = '/pathway/reaction[/pathway/entry/@id=@id]';

if (my ($reaction) = $data->findnodes($query)) {
  say "substrate:::", $reaction->findvalue('substrate/@id');
  say "product:::", $_->textContent for $reaction->findnodes('product/@id');
}

输出:

substrate:::105
product:::132
product:::89
于 2013-09-04T15:28:24.333 回答