2011-01-22 99 views
1

對不起,不清楚。 我想傳達的問題是,XML::Simple不允許我直接訪問散列,我必須通過XML::Simple模塊參考有問題的密鑰。使用類似$xml->{key}任何人都可以推薦解決方案,以我的情況與XML

這是我使用的代碼和散列輸出的副本。

這是一個問題的原因是因爲我需要使用哈希鍵(見下文)構建一系列循環,並且我不能用哈希引用構建一個foreach循環,當我嘗試時,perl給出了我錯了。

所以我在尋找的是一個模塊或解決方案,允許我將XML文件的內容轉儲爲我在腳本中聲明的散列。我還需要能夠寫回到一個XML文件。

#!/usr/bin/perl 
use strict; 
use warnings; 
use XML::Simple; 
use Data::Dumper; 

system ("clear"); 

my $xml = XML::Simple->new; 

# Using the XML::Simple object, read guest_os.xml to a hash 

my $xml_file = $xml->XMLin('config.xml', 

       SearchPath => './config', 

       SuppressEmpty => 1); 




$VAR1 = \{ 
     'esxi01' => { 
        'password' => 'myspoonistoobig!', 
        'user' => 'root', 
        'port' => '22' 
        }, 
     'esxi02' => { 
        'password' => 'myspoonistoobig!', 
        'user' => 'root', 
        'port' => '22' 
        }, 
     'Setup' => 'FALSE' 
     }; 

對於我訪問創建的哈希中的單個鍵/值[上述]我必須使用這樣的東西。

$ xml_file - > {esxi01} {密碼}。

哦,是的,我忘了實際的XML文件。

<Config> 
    <esxi01> 
    <password>password</password> 
    <port>22</port> 
    <user>root</user> 
    </esxi01> 
    <esxi02> 
    <password>password</password> 
    <port>22</port> 
    <user>root</user> 
    </esxi02> 
    <Setup>FALSE</Setup> 
</Config> 

這是3我左右最簡單的。

更新:

循環的第一部分作品沒有問題,當我嘗試使用循環的第二部分的問題發生。

這裏是我的代碼看起來

my $xml = XML::Simple->new; 

# Using the XML::Simple object, read guest_os.xml to a hash 

my $xml_file = $xml->XMLin('config.xml', 

       SearchPath => './config', 

       SuppressEmpty => 1); 

foreach my $server (keys %$xml_file) { 
    foreach my $attribute (keys %{$xml_file->{$server}}) { 
     print "$attribute\n"; 
    } 
} 

輸出類似於這樣的方式,

Can't use string ("password") as a HASH ref while "strict refs" in use at foreach_test line 21.

我已經用在幾個地方引號來解決這個問題嘗試,但似乎沒有任何工作。

+1

對不起,但這絕對沒有意義。你可以提供模式詳細的例子,你的意思是「因爲爲了訪問它創建的散列,我必須使用像$ xml - > {key}這樣的函數來獲取數據。這對我來說是個問題,因爲我無法循環模塊設置的散列中的鍵「? – DVK 2011-01-22 22:02:04

+0

我覺得你很困惑 - 在代碼中你沒有通過XML :: Simple模塊訪問數據$ xml_file是從XML返回的數據結構(即表示XML數據的哈希引用):: Simple- > XMLin。要查看從XML :: Simple返回的數據結構,請查看Data :: Dumper(`print dumper($ xml_file)`)將顯示解析XML所得到的結果) – plusplus 2011-01-24 17:12:07

回答

4

我不知道,如果我知道你需要什麼正確的 - 問題是非常混亂。你要問的是:

  • 你有一個複雜的嵌套XML。例如。 <t1><t2><t3>value</t3></t2></t1>

  • 您似乎想要訪問標記<t3>的內容,但不需要通過XML :: Simple創建的用於表示DOM的哈希散列值的散列值的哈希鍵。例如。你不想做$xml->{t1}->{t2}->{t3}

如果是這樣的話,您的問題是您使用的是DOM解析器。 SAX解析器(如XML::Twig)可讓您在解析特定標記時執行事件,例如無論標籤在什麼地方,都是如此。


如果你的問題是,你只是不知道這存在標籤(如鍵在哈希), 你可以做keys %$xmlkeys %{ $xml->{t1} }一一列舉。

UPDATE

要使用你的榜樣循環:

foreach my $key (keys %$xml) { # $key will be esxi01, etc... 
    foreach my $attribute (keys %{ $xml->{$key} }) { 
     "Key: $key; attribute: $attribute; value: $xml->{$key}->{$attribute}\n"; 
    } 
    print "Port for $key: $xml->{$key}->{port}\n"; # Hardcoded 
} 

UPDATE2

的問題是在<Setup>FALSE</Setup> XML標籤。它沒有子標籤,所以在散列中它的值將是標量而不是散列。要解決這個問題,你需要檢查內部元素是否確實是一個散列:

foreach my $server (keys %$xml_file) { 
    next if (ref ($xml_file->{$server}) ne ref({})); # Not a hash 
    foreach my $attribute (keys %{$xml_file->{$server}}) { 
     print "$attribute\n"; 
    } 
} 
2

您可以通過使用eachkeys哈希迭代:

while(($key, $value) = each(%$xml)) { 
    print "key: $key, value: $value\n"; 
} 

foreach my $key (keys %$xml) { 
    print "key: $key, value: $xml->{$key}\n"; 
} 
相關問題