2013-09-04 3 views
0

J'ai un fichier xml et je veux comparer les ids du noeud d'entrée à l'id du noeud de réaction et si sont les mêmes que l'exemple ci-dessous je veux accéder à toutes les informations de réaction (identifiant du substrat et identifiant du produit). J'ai deux id produit et ce code donne le premier Voici le fichier XMLComment récupérer un noeud avec le même nom en XML simple en perl

<?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> 

Voici mon code

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"; 
    } 
    } 
} 

Répondre

1

XML :: Simple est tout sauf simple. Sa propre documentation discourages further use de ce module.

La structure de données que vous pourriez obtenir (qui sait?) Est sur mon système:

{ 
    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", 
       }, 
} 

Il est toujours bon de inpect une structure de données lorsque vous n'êtes pas sûr si vous accédez correctement. Une façon de le faire est use Data::Dumper; print Dumper $data. Vous pouvez remarquer qu'il n'y a aucun champ pour id dans le entry. En outre, les product ne possèdent pas de champ ID, mais utilisent plutôt l'attribut name comme nom. * Soupir * - ce genre d '"intelligence" est pourquoi vous ne devriez pas utiliser XML :: Simple.


Il est beaucoup plus facile d'utiliser un analyseur syntaxique comme XML::LibXML. On peut alors utiliser XPath pour sélectionner des noeuds que nous voulons:

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

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

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

Sortie:

substrate:::105 
product:::132 
product:::89 
Questions connexes