2009-03-18 3 views
2

J'essaie simplement de récupérer un attribut de XML dans mon programme Perl. Cependant, j'ai des problèmes pour récupérer les attributs. J'ai utilisé XML::Simple.Comment puis-je récupérer des attributs de balise avec XML :: Simple?

Je peux récupérer des informations bien quand XML est comme ceci:

<IdList> 
    <Id>17175540</Id> 
</IdList> 

en utilisant ce code

$data->{'DocSum'}->{'Id'}; 

Cependant, lorsque le XML est comme ceci:

<Item Name="Title" Type="String"> 
    Some Title 
</Item> 

I Je ne reçois aucune donnée lors de l'utilisation du code suivant

$data->{'DocSum'}->{'Title'}; 

BTW, c'est le lien que je reçois le XML de http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id=19288470

+0

En note, vous n'avez pas besoin de -> entre {'DocSum'} et {'Title'}. Vous n'avez pas non plus besoin des «citations». $ data -> {DocSum} {Title} devrait convenir. –

Répondre

3

Je pris le xml de cette page que vous avez fourni, utilisé la chose entière comme une chaîne pour l'argument à XMLIN et eu du succès avec

print $data->{DocSum}->{Item}->[5]->{content}; 

donnant la sortie

dégradation bromoxynil un sol limoneux du Mississippi.

C'est à peu près la même chose que disait Derobert.

Edit:

Plutôt que d'assumer le 6e élément d'objet est celui que vous recherchez, pour imprimer le contenu du nœud où l'attribut Name est « Titre » (puis sortir de la boucle puisque vous avez trouvé ce que vous voulez):

foreach my $item_node (@{$data->{DocSum}->{Item}}) 
{ 
    if($item_node->{Name} eq 'Title') 
    { 
     print $item_node->{content}; 
     last; 
    } 
} 

Bien sûr, cela est toujours à la recherche uniquement sur les nœuds de l'objet immédiatement sous DocSum, donc si vous cherchez PubType au lieu du titre, il ne serait pas trouvé en raison de cette étant un enfant du noeud PubTypeList Item.

+0

XML n'est pas positionnel comme ça. Cela fonctionne, mais est très fragile. Il vaudrait mieux chercher le bit name = Title. Je vais écrire un exemple plus tard aujourd'hui si vous ne me l'avez pas battu :-D – derobert

+0

Juste point, ma réponse originale était principalement d'aller au contenu en général, mais j'ai ajouté un code plus intelligent qui fait la recherche pour le noeud spécifique. – Cebjyre

+0

Cela me semble bon. – derobert

2

Je suppose que vous utilisez XML :: Simple pour analyser XML. Je suggère que vous vider votre structure de données en utilisant Data::Dumper. Vous devriez pouvoir le trouver assez facilement alors.

use Data::Dumper; 
print Dumper($data); 
+0

J'utilise dumper pour imprimer des données sur l'écran et il montre {'Type' => 'String', 'content' => 'Un titre', 'Name' => 'Title'} –

+0

Titre est la valeur de la entité, pas l'ID/clé. Cherchez-vous "Un titre" ou "Titre"? – weismat

+0

Je suis à la recherche de "Some Title". Qui est sous 'Contenu' mais même si je fais $ dataSummary -> {'DocSum'} -> {'Title'} -> {'content'}; Je ne reçois pas 'Some Title' –

4

course:

$ perl -MXML::Simple -M'Data::Dump qw/pp/' 
my $ref = XMLin('<Item Name="Title" Type="String">Some Title</Item>'); 
pp $ref; 

sortie:

{ Name => "Title", Type => "String", content => "Some Title" } 

Ainsi, il semble que vous devriez regarder sous la rubrique 'contenu' pour le trouver.

+0

J'ai essayé $ dataSummary -> {'DocSum'} -> {'Title'} -> {'content'}; mais même cela ne fonctionne pas –

+0

Vous n'avez pas publié le XML complet, mais essayez quelque chose comme $ data -> {'DocSum'} {'content'}. Aucun indice là où il se trouve exactement dans votre structure, sauf si vous publiez suffisamment de XML pour que je puisse recréer votre structure, ou bien publier le Data :: Dump [er] de votre structure. – derobert

+0

c'est le xml complet http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id=19288470 dumper est assez grand pour poster ici –

1

Il semble que XML :: Simple ne sache pas exactement comment transformer les données. Avez-vous essayé de mélanger l'option KeyAttr de XMLin()?

2

Mais, bien sûr, 'Titre' n'est pas une clé, mais une valeur d'attribut, et donc une valeur de hachage. Vous avez besoin XPath et vous pouvez spécifier /DocSum/Item[@Name='Title']

L'équivalent en XML :: Simple (ou Perl), est

my ($item) = grep { $_->{Name} eq 'Title' } @{$data->{DocSum}{Item}}; 

ou même

use List::Util qw<first>; 
... 
(first { $_->{Name} eq 'Title' } @{$data->{DocSum}{Item}})->{content}; 

Je suis en désaccord avec daotoad . Cela ne transforme pas les données aussi loin que je peux le voir. Vous n'êtes simplement pas travaillant avec ce qu'il produit correctement. C'est un Simple module, ce n'est pas robuste, et pas trop DWIM.

Questions connexes