很抱歉不清楚。
我试图传达的问题是XML::Simple不允许我直接访问哈希,我必须通过XML::Simple模块引用有问题的密钥。使用类似$xml->{key}
的内容。
这是我正在使用的代码和散列输出的副本。
这是一个问题的原因是因为我需要使用哈希的键来构造一系列循环[见下文],我无法使用哈希引用构建一个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.
我尝试在几个地方使用引号来解决问题,但似乎没有任何工作。
答案 0 :(得分:4)
我不确定我是否理解你的需要 - 问题非常混乱。你要问的是:
您有一个复杂的嵌套XML。例如。 <t1><t2><t3>value</t3></t2></t1>
您似乎想要访问标记<t3>
的内容,但无需通过XML :: Simple创建的数据结构的哈希哈希值中的哈希键代表DOM。例如。你不想做$xml->{t1}->{t2}->{t3}
。
如果是这种情况,那么您的问题是您正在使用DOM解析器。 SAX解析器(如XML::Twig
)允许您在解析特定标记时执行事件,例如t3
无论标签在哪个结构中都是如此。
如果您的问题是您只是不知道哪些标签存在(作为哈希中的键),
您可以keys %$xml
或keys %{ $xml->{t1} }
列出它们。
<强>更新强>
使用您的示例循环:
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标记中。它没有子标签,因此在散列中它的值将是SCALAR而不是散列。要修复,您需要检查内部元素是否确实是哈希:
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";
}
}
答案 1 :(得分:2)
您可以使用each
或keys
:
while(($key, $value) = each(%$xml)) {
print "key: $key, value: $value\n";
}
foreach my $key (keys %$xml) {
print "key: $key, value: $xml->{$key}\n";
}