2012-01-17 17 views
1

私はPerlでxmlファイルを解析していますが、すべてが1つの問題でうまくいくようです。私は同じスキーマを持つファイルを持っていますが、パーサから異なる種類のデータを返しています。ここで簡単な例である:データの同様のセットのために、(2つのハッシュの配列であるテストに注意してください)Perl、XMLでXMLを解析する::シンプルで問題がある

$VAR1 = { 
      'test' => [ 
        { 
         'data2' => 'Hello', 
         'data1' => 'Hi' 
        }, 
        { 
         'data2' => 'Hello2', 
         'data1' => 'Hi2' 
        } 
        ] 
     }; 

ここで、:ダンプで

<tests> 
     <test> 
      <data1>Hi</data1> 
      <data2>Hello</data2> 
     </test> 
     <test> 
      <data1>Hi2</data1> 
      <data2>Hello2</data2> 
     </test> 
    </tests> 

、これは以下を返しますしかしこれ等つのみ「テスト」エンティティと:試験エンティティがもはや配列が、特異ハッシュされることを除い

<tests> 
     <test> 
      <data1>Hi</data1> 
      <data2>Hello</data2> 
     </test> 
    </tests> 

これは、同様のデータを返さない:

$VAR1 = { 
      'test' => { 
        'data2' => 'Hello', 
        'data1' => 'Hi' 
        } 
     }; 

私のジレンマは、私のコードでは、そこに配列があると予想しているということです。しかし、1つのエンティティだけが存在するスリムなチャンスでは、そのエンティティのハッシュが返されます。私の質問は、配列のようにハッシュエンティティをどのように扱うことができるかということです。またはそれをテストしますか?

今の配列を取得するための私のコードは次のようである:

foreach $test (@{$data->{'tests'}->{'test'}}) 
{ 
    do something with $test 
} 

しかし、ハッシュと、それはエラー「未ARRAYのリファレンス」を与えます。私はこれが十分な詳細だと思う!ありがとう!!!

答えて

6

がある場合でも配列として を表現するネストされた要素を強制的に「1」に設定されなければなりませんForceArrayオプションは何ですか?

ForceArray => [名]

この代替(そして好ましい)「ForceArray」オプション のフォームは、あなたが常に が配列表現に強制されなければならない要素名のリストを指定することができ、上記の「すべてかどうか」 のアプローチではなく、

コンパイル済みの通常の 式をリストに含めることも可能です。パターン に一致する要素名はすべて強制的に配列になります。リストに単一の正規表現が含まれている場合は、 をarrayrefに囲む必要はありません。例:

ForceArray => QR/_list $/

だから私は試してみてください:

ForceArray => ['test'] 
+1

ありがとう!これは私にとって完璧に機能しました! – srowley

0

ハッシュsigil: '%'を使用してハッシュを逆参照する必要があります。

1

XML::Simple

ForceArray => 1 

このオプションはおそらく代替形態つのみ

+0

私はこれを試みたが、それができすべてのハッシュを配列に設定します。私にできることはほかにありますか? – srowley

0

それはあなたがXMLパーサはより一貫振る舞うために得ることができると思わ一方で、それはまた、希望バリアント出力でコードを動作させることは難しくありません。

リファレンスが参照するオブジェクトのタイプを決定するために、Perlビルトイン関数 "ref"を使用できます。 > { 'テスト'} - -

あなたの元のコードは

foreach $test (@{$data->{'tests'}->{'test'}}) 
{ 
    do something with $test 
} 

(むしろ書き込み$データより行く> { 'テスト'}、私はよりコンパクト$$データ{テスト}を使用する傾向があります{試験}、私は私の例ではそれを使用します。)

我々は、参照タイプをチェックし、配列にすべての可能性を押してそれを使用するので、

foreach $test (
    (ref($$data{tests}{test}) eq 'ARRAY') ? (
     @{$$data{tests}{test}} 
    ) : (
     $$data{tests}{test} 
    ) 
) 
{ 
    do something with $test 
}