2011-10-19 29 views
1

我解析的XML ::簡單的使用這些選項我應該如何處理XML :: Simple的未定義引用?

my $xml = XML::Simple->new(ForceArray => 1, KeyAttr => 1, KeepRoot => 1); 

這是一個示例XML文檔

<ip> 
    <hostname>foo</hostname> 
    <info>server</info> 
    <soluton>N/A</solution> 
    <cats> 
     <cat> 
      <title>Baz</title> 
      <flags>0</flags> 
     </cat> 
     <cat><title>FooBar</title></cat> 
    </cats> 
</ip> 
<ip> 
    <info>client</info> 
    <diagnosis>N/A</diagnosis> 
    <cats> 
     <cat><title>Foo</title></cat> 
     <cat> 
      <title>Bar</title> 
      <update>Date</update> 
     </cat> 
    </cats> 
</ip> 

正如你所看到的,不是每一個節點都具有主機屬性的XML文件,這導致我的腳本一起死的,當我試圖讓主機

$nb = "@{ $_->{hostname} }"; 

有幾個OPTIO「不能用一個未定義的值作爲數組引用」錯誤在xml中的最終元素(十幾個)。我應該如何處理? 我應該在作業之前檢查元素的存在嗎?

if (@{ $_->{hostname}) { $nb = "@{ $_->{hostname} }" } 
if (@{ $_->{solution}) { $s = "@{ $_->{solution} }" } 
if (@{ $_->{diagnosis}) {...} 

我應該使用eval塊嗎?

eval { $nb = "@{ $_->{hostname} }" }; 

也許

eval { 
    $nb = "@{ $_->{hostname} }"; 
    $s = "@{ $_->{solution} }"; 
    $d = "@{ $_->{diagnosis} }"; 
}; 

有沒有更好的辦法?

+0

參見:從XML ::簡單加緊XML ::的libxml(http://www.perlmonks.org/index.pl?node_id= 490846) –

+0

您提供的兩種解決方案(使用* if *或使用* eval *檢查值)都適合我。 – m0skit0

回答

0

首先,你真的需要'ForceArray'選項嗎?也許最好使用標量值並檢查它們(可能)在哪裏的數組?

解到陣列-可待未定義我使用的引用是:

my $string = join '', @{ $var || [] }; 

這意味着「間接引用變量或空匿名數組引用」。

你的情況,這將是

$nb = join '', @{ $_->{hostname} || [] }; 
+0

我啓用強制陣列,因爲真正的XML比示例更復雜。 (這是一個Qualys掃描報告,有大量的嵌套元素和列表) – Tucan

+0

@Tucan比上面的解決方案應該可以幫到你。 – yko