2016-12-19 11 views
2

私は(データはダンプ)このAPIとAPIリターンに渡すXMLを作成しています:私の人生のために私はをループにしたいperlではどのようにこの構造をループするのですか?

(
    "Data::Dump", 
    { 
     SiteDevices => { 
     "device" => { 
         1102 => { address => "1.2.3.4", riskfactor => "1.0", riskscore => "0.0" }, 
         1136 => { address => "1.2.3.5", riskfactor => "1.0", riskscore => "0.0" }, 
         20491 => { address => "1.2.3.6", riskfactor => "1.0", riskscore => "0.0" }, 
         129644 => { address => "1.2.3.7", riskfactor => "1.0", riskscore => "0.0" }, 
         129645 => { address => "1.2.3.8", riskfactor => "1.0", riskscore => "0.0" }, 
         130408 => { address => "1.2.3.9", riskfactor => "1.0", riskscore => "0.0" }, 
         135975 => { address => "1.2.3.10", riskfactor => "1.0", riskscore => "0.0" }, 
         137642 => { address => "1.2.3.11", riskfactor => "1.0", riskscore => "0.0" }, 
        }, 
     "site-id" => 27, 
     }, 
     success => 1, 
    }, 
) 

とそれらに関連付けられているデバイスとIPを印刷し、Iそれを行うためのコードを思いつくことはできません。一体何が欠けているのですか?私はハッシュ、ハッシュのハッシュなどをループしようとしました。それが動作することは決してできません。もしあなたのいずれかが秒を持っていて、答えを与えることができるなら、私は驚くべきことに頭を振ることができます。

私が試してみました:

foreach my $key (keys %{ $output->{‘SiteDevices’}->{‘device’} }) { 
     print $key 
     print $key->{‘address’} 
} 

foreach my $key (keys %{ $output{‘SiteDevices’}{‘device’} }) { 
     print $key 
     print $key{‘address’} 
} 

どちらも作品を。

+0

いくつの 'SiteDevices'エントリが出力にありますか?一つだけ? – stevieb

+0

これは解析されたXMLに似ているようです。万が一ですか?もしそうなら、私は、より良いパーサーを使用して、より上流で作業するほうが良いと思っています。 XMLの例を追加すれば、より良い例を提供することがはるかに簡単になります。 – Sobrique

答えて

5

あなたは、この解析されるXMLに言及。それはあなたがXML::Simplethat's just not a good idea.

でそれを解析されてきたように見えるのはなぜない代わりに:

#!/usr/bin/env perl 
use strict; 
use warnings; 

use XML::Twig; 

## get xml somehow here. parsefile if it's a file already. 
my $twig = XML::Twig -> new -> parse ($your_xml); 

foreach my $device ($twig -> get_xpath('//devices')) { 
    print $device -> att('name'), " => "; 
    print $device -> att('address'),"\n"; 
} 

ここに有用なものがxpathある - それは正規表現ではないが、それは一種の似ている - と、それが適用されますXML。この場合、//deviceは、 '<device>ノードをツリーのどこかで見つけることができます。 (そして属性を抽出する)。直接現在のノードの下に -

  • ./device:あなたのシナリオのために働くかもしれないが、あなたは長いパスを指定することで、より具体的なことができ

  • .//device - 現在のノードの下の任意の場所。
  • /root/SiteDevices/device - この 'ツリー'に特に一致するノード。

また、属性に検索するxpathを使用することができます。

  • .//device[@name="1136"]が適切な値と属性を持つ何かを見つけるでしょう。

この方法のガイドについては、XML Twigクイックリファレンスを参照してください。

+1

私はこれをありがとう!私はこれを理解しようと数日間、テーブルの上で頭を打っています。そして、あなたはそれを数秒で修正しました。私はそれをダンプし、その中に狂った量の情報を持っているので、小枝がどのように機能するかをもう少し読んで行くつもりです。しかし、ループは必要な情報を印刷します!!! – robamcclellan

+1

@robamcclellan:SobriqueはXPathの '// devices'を使っています。これはドキュメント内のどこにでも' devices'ノードをすべて見つけます。 XMLデータを見ていないのでルート要素の名前がわからないので、彼が選んだのは私の推測です。通常、 '/ root/SiteDevices/device'のようなものを使ってノードをより具体的に分離するのが最善でしょうが、' root'が何であるべきかを知ることはできません。 – Borodin

+1

@robamcclellanおそらく、XML :: Twig(またはXML :: Twig :: Elt)オブジェクトをダンプしたくないでしょう。それをソーセージと考えてください;)あなたはツリー表現を得るために '_dump'メソッドを使うことができますが、実際にはXMLをきれいに印刷することは有益なものです。有用なメソッドの最初のリストについては、http://xmltwig.org/xmltwig/quick_ref.htmlを参照してください。 – mirod

2

私は次のループがあなたが達成しようとしていることをすると信じています。あなたのテストでは

for my $device (keys %{ $output->{SiteDevices}{device} }){ 
    print "$device: $output->{SiteDevices}{device}{$device}{address}\n"; 
} 

、あなたは動作しませんこれは、ハッシュ/ハッシュリファレンスとしてキー名を使用しようとしている:それは、そのアドレスを抽出し、両方を印刷し、木から各デバイスをフェッチ。抽出を実行するには、抽出したキーをハッシュに戻す必要があります。

私はあなたの質問のうち、抽出された単一のレコードに基づいて出力、:

129644: 1.2.3.7 
129645: 1.2.3.8 
130408: 1.2.3.9 
137642: 1.2.3.11 
1136: 1.2.3.5 
135975: 1.2.3.10 
1102: 1.2.3.4 
20491: 1.2.3.6 
関連する問題