2012-01-17 77 views
1

我使用Perl解析xml文件,並且所有內容似乎都很適用於一個問題。我有具有相同模式的文件,但他們從解析器返回不同類型的數據。下面是一個簡化的例子:Perl,使用XML解析XML :: Simple和存在問題

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

在轉儲中,該返回如下:(乘測試是兩個散列陣列的註釋)

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

現在,對於一組類似的數據的,但只有一個「測試」實體,像這樣:

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

這返回類似的數據,除了測試實體不再是一個數組,但奇異散列:

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

我的兩難處境是我的代碼期望有一個數組,因爲這是常態。但是,只有一個實體的機會很小,它會爲該實體返回一個散列。我的問題是,我如何處理哈希實體,就像它是一個數組一樣。或者測試它?

現在我的檢索數組的代碼是這樣的:

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

但是隨着散列,它提供了一個錯誤「不是一個數組引用」。我希望這是足夠的細節!謝謝!!!

回答

6

或許替換形式的,即使ForceArray選項是你想要的嗎?

ForceArray => [名稱]

的「ForceArray」選項的這種替代(和優選的)形式 允許用戶指定應該始終被 被迫進入一個數組表示元素名稱的列表,而不是上面的「全部或全部」 方法。

也可以(自2.05版),包括編譯的正則表達式 在列表中 - 匹配的模式 將被迫陣列的任何元素名稱。如果列表只包含一個正則表達式,則 則不必將其包含在arrayref中。例如:

ForceArray => QR/_list $/

所以我可能會嘗試:

ForceArray => ['test'] 
+1

謝謝!這對我來說非常合適! – srowley 2012-01-17 02:27:49

0

您需要通過使用哈希符號來取消引用哈希值:'%'。

1

XML::Simple

ForceArray => 1 

此選項應該被設置爲「1」以強制嵌套元素是表示爲陣列 僅存在一個

+0

我想這一點,但隨後將所有散列設置爲數組。還有什麼我可以做的嗎? – srowley 2012-01-17 01:38:35

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 
}