任何人都可以推荐使用XML解决我的问题

时间:2011-01-22 21:58:01

标签: xml perl configuration-files

很抱歉不清楚。 我试图传达的问题是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.

我尝试在几个地方使用引号来解决问题,但似乎没有任何工作。

2 个答案:

答案 0 :(得分:4)

我不确定我是否理解你的需要 - 问题非常混乱。你要问的是:

  • 您有一个复杂的嵌套XML。例如。 <t1><t2><t3>value</t3></t2></t1>

  • 您似乎想要访问标记<t3>的内容,但无需通过XML :: Simple创建的数据结构的哈希哈希值中的哈希键代表DOM。例如。你不想做$xml->{t1}->{t2}->{t3}

如果是这种情况,那么您的问题是您正在使用DOM解析器。 SAX解析器(如XML::Twig)允许您在解析特定标记时执行事件,例如t3无论标签在哪个结构中都是如此。


如果您的问题是您只是不知道哪些标签存在(作为哈希中的键), 您可以keys %$xmlkeys %{ $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)

您可以使用eachkeys

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

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