2009-03-18 13 views
3

私は昨日、私はXMLを取得するために使用していますHow do I retrieve tag attributes with XML::Simple?リンク質問を:私は非常に良い進歩を遂げたとをループ以下のコードを書いた1つまたは複数のサブ要素を持つXMLタグでXML :: Simpleを使用するにはどうすればよいですか?

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)

をタグと必要なものを検索します。私は「ArticleIds」

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; 

       } 
     } 

の下にこのコードは、基本的にArticleIdsタグを検索し、次に「はDOI」タグを見つけるために、その下にサブタグを検索「DOI」タグを探しています。

問題ArticleIdsに(2)のように複数のサブタグがある場合、すべて正常に機能します。しかし、ArticleIdsタグの下に(1)に示すように1つのサブタグしかない場合、エラーが発生し、プログラムが停止します。

私はSimple Parserを使用しており、ダンパーを使用して2つの結果が得られました。 は、ここで(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' } 

あなたが見ることができるようにリンクのリンク(1)のダンプ の一部

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

です。 ArticleIdsの下に複数のタグがある場合、それは配列として扱われます。したがって、大括弧で囲まれています。

誰かがこのような場合に何を提案しますか?

答えて

6

ファイルにItem要素のいずれかが1つしかない場合、その項目はハッシュで表示されます。 Item要素が複数ある場合は、配列として表示されます。 ForceArrayオプションを使用して、特定のタグに常にリストが含まれるようにすることができます。配列に強制的に追加するすべての属性名の正規表現を渡すと、残りの部分が処理されます。

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

また、使用しているXML :: Simpleのバージョンも確認してください。以前のバージョンでは、ForceArrayで値の配列refを指定することしかできなかったか、まったく動作しなかったと思います。それが唯一の配列リファレンスで動作する場合は、あなたがそれを指定することができます。

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

あなたを助けることが、より多くのオプションを見るためにThe XML::Simple CPAN documentationをチェックしてください。

バージョンまでは、ActiveStateディストリビューションに付属しているXML :: Simpleを使用している場合は、バージョンが古くなっている可能性があります。新しいものをつかんでみてください。

また、それが何であるかの種類を確認し、どちらか(あなたが発見したとして)

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

私は以下のことをしましたが、アイテムが1つしかありません。それはハッシュで来ています。 $ contents = get($ getstring) $ data = $ xml-> XMLin($ contents、ForceArray => qr {Item} x); –

+0

私は配列に入れたいItemタグがArticleIdsタグの下にあるので何か違いがありますか? –

+0

これはイライラしています... :(XMLを知るための素早い方法はありますか::使用しているシンプルなバージョンですか? –

4

は、私はあなたがしている問題の一つだと思い

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

またはREFキーワードを使用することができますあなたはXML :: Simpleのどこかにあなたが十分なノブとダイヤルを与えていないということですが、問題はより複雑なものを書くのに十分複雑です。

この場合、私はXML::Twigのようなものに手を伸ばします。より多くのイベント駆動型なので、XML全体を歩き回り、必要なときにコントロールすることができます。あなたが好きな要素を手に入れたら、好きなことを何でもできます。

Twigのようなものの他に、XPathなどのさまざまなものが同じように便利です。 XML :: Simpleとは異なり、データ構造を提供するのと違って、XMLを深く掘り下げてその一部を引き出すように作られています。

1

私はXML上で古いバージョンを持っていました::シンプルなので、ref()関数を使用してコードを追加しました。

ありがとうございました

+0

私は通常それを処理します。 –

関連する問題