1

Perl で xml ファイルを解析していますが、すべてが 1 つの問題でうまく機能しているようです。同じスキーマのファイルがありますが、パーサーから異なるタイプのデータが返されます。簡単な例を次に示します。

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

ダンプでは、これは次を返します: (test は 2 つのハッシュの配列であることに注意してください)

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

さて、同様のデータセットですが、次のような「テスト」エンティティは 1 つだけです。

  <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参照ではありません」というエラーが発生します。これが十分な詳細であることを願っています!ありがとう!!!

4

4 に答える 4

6

おそらく、ForceArrayオプションの代替形式が必要ですか?

ForceArray => [名前]

'ForceArray' オプションのこの代替 (および推奨) 形式を使用すると、上記の 'すべてかゼロか' アプローチではなく、常に強制的に配列表現にする必要がある要素名のリストを指定できます。

(バージョン 2.05 以降) コンパイル済みの正規表現をリストに含めることもできます。パターンに一致する要素名はすべて強制的に配列になります。リストに含まれる正規表現が 1 つだけの場合は、それを arrayref で囲む必要はありません。例えば:

ForceArray => qr/_list$/

だから私は試すかもしれません:

ForceArray => ['test']
于 2012-01-17T02:07:53.573 に答える
1

XML::シンプル

ForceArray => 1

このオプションを「1」に設定して、ネストされた要素が 1 つしかない場合でも強制的に配列として表されるようにする必要があります。

于 2012-01-17T01:14:58.323 に答える
0

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

于 2012-01-17T01:11:23.590 に答える
0

XML パーサーの動作をより一貫性のあるものにすることができるように見えますが、バリアント出力でコードを機能させることも難しくありません。

Perl 組み込み関数「ref」を使用して、参照が参照するオブジェクトのタイプを判別できます。

元のコードは

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

( $data->{'tests'}->{'test'} と書くよりも、よりコンパクトな $$data{tests}{test} を使用する傾向があるため、例ではそれを使用します。)

参照型を確認し、それを使用してすべての可能性を配列にプッシュできます。

foreach $test (
    (ref($$data{tests}{test}) eq 'ARRAY') ? (
        @{$$data{tests}{test}}
    ) : (
        $$data{tests}{test}
    )
)
{
    do something with $test
}
于 2012-01-21T22:47:28.157 に答える