2009-03-18 8 views
3

J'ai demandé un lien question hier How do I retrieve tag attributes with XML::Simple? J'utilise pour obtenir le XML:Comment utiliser XML :: Simple avec des balises XML pouvant contenir un ou plusieurs sous-éléments?

http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id=19273512 (1)

http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id=19291509 (2)

J'ai fait de très bons progrès et écrit le code suivant qui fait une boucle par les balises et les recherches pour ceux dont j'ai besoin. Je cherche tag 'doi' sous 'ArticleIds de

foreach $item_node (@{$dataSummary->{DocSum}->{Item}}) 
     { 
       if($item_node->{Name} eq 'ArticleIds') 
       { 
         foreach $item_node1 (@{$item_node->{Item}}) 
         { 
           if ($item_node1->{Name} eq 'doi') 
           { 
            $doi= $item_node1->{content}; 
            last; 
           } 
         } 
         last; 

       } 
     } 

Ce code recherche essentiellement pour la balise de ArticleIds et recherche ensuite subtags dessous pour trouver tag 'doi'. Le problème que je rencontre est que lorsque ArticleIds a plusieurs sous-balises sous lui (comme on peut le voir dans (2)) alors tout fonctionne bien. Cependant, lorsque la balise ArticleIds ne comporte qu'une seule sous-balise (comme indiqué en (1)), il y a des erreurs et le programme s'arrête. J'utilise le Simple Parser et en utilisant le dumper j'ai obtenu deux résultats. Voici une partie de la décharge pour le lien (1)

{ 'Type' => 'List', 'Item' => { 'Type' => 'String', 'content' => '19273512', 'Name' => 'pubmed' }, 'Name' => 'ArticleIds' } 

pour le lien (2)

{ 'Type' => 'List', 'Item' => [ { 'Type' => 'String', 'content' => '909564644', 'Name' => 'pii' }, { 'Type' => 'String', 'content' => '10.1080/13506120802676914', 'Name' => 'doi' }, { 'Type' => 'String', 'content' => '19291509', 'Name' => 'pubmed' } ], 'Name' => 'ArticleIds' } 

Comme vous pouvez le voir. quand il y a plusieurs étiquettes sous ArticleIds alors il est traité comme un tableau, d'où les crochets.

Qu'est-ce que quelqu'un pourrait suggérer dans un cas comme celui-ci?

Répondre

6

Si le fichier ne contient qu'un des éléments Item, l'élément apparaîtra dans un hachage. S'il y a plusieurs éléments Item, alors il apparaîtra comme un tableau. Vous pouvez forcer certaines balises à toujours contenir une liste à l'aide de l'option ForceArray. Passez-lui une expression régulière de tous les noms d'attributs que vous souhaitez forcer dans un tableau, et il s'occupera du reste.

XMLin('file.xml', 
     ForceArray => qr{Item}x); 

Oh, vérifiez également quelle version de XML :: Simple vous utilisez. Je pense que les versions précédentes ne pouvaient spécifier qu'un tableau array de valeurs avec ForceArray, ou cela ne fonctionnait pas du tout. Si elle ne fonctionne qu'avec un arrayref, vous pouvez spécifier avec:

XMLin('file.xml', 
     ForceArray => [ 'Item' ]); 

Découvrez The XML::Simple CPAN documentation pour plus d'options qui peuvent vous aider. En ce qui concerne la version, si vous utilisez XML :: Simple fourni avec, disons, une distribution ActiveState, elle est probablement périmée. Essayez d'en saisir un nouveau.

Vous pouvez également vérifier quel type il est, soit à l'aide

$item =~ /HASH/ # hash 
$item =~ /ARRAY/ # array 

ou le mot-clé ref (comme vous découvriez)

ref($item) eq 'HASH' 
ref($item) eq 'ARRAY' 
+0

J'ai fait ce qui suit mais toujours s'il n'y a qu'un seul élément. Il vient dans un hachage. $ contents = get ($ getstring) $ données = $ xml-> XMLin ($ contents, ForceArray => qr {Item} x); –

+0

dois-je faire quelque chose de différent puisque la balise Item que je veux mettre dans un tableau est sous tag ArticleIds? –

+0

c'est frustrant ... :(est-il un moyen rapide de trouver la version XML :: Simple que j'utilise? –

4

Je pense que l'un des problèmes que vous êtes avoir est que vous êtes quelque part entre XML :: Simple ne vous donne pas assez de boutons et de cadrans, mais le problème n'est pas assez compliqué pour que vous écriviez quelque chose de plus compliqué.

Dans ce cas, je voudrais atteindre quelque chose comme XML::Twig. Il est plus piloté par les événements afin qu'il puisse traverser votre XML et vous donner le contrôle quand vous le voulez. Une fois que vous obtenez l'élément que vous aimez, vous pouvez faire ce que vous voulez avec.

En plus des choses comme Twig, diverses choses comme XPath et ainsi de suite peuvent être utiles de la même manière. Ils sont construits pour regarder en profondeur dans XML pour en extraire des parties, contrairement à XML :: Simple qui vous donne juste une structure de données.

1

J'avais une ancienne version sur XML :: Simple J'ai donc décidé d'utiliser la fonction ref() et d'écrire des lignes de code supplémentaires.

Merci pour l'aide

+0

C'est la comme je le gère habituellement. –

Questions connexes