Может кто-нибудь порекомендовать решение моей ситуации с XML - PullRequest
1 голос
/ 23 января 2011

Извините, что не ясно. Проблема, которую я пытаюсь донести, состоит в том, что 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>

Это самый простой из трех или около того, что у меня есть.

Обновление:

Первая часть цикла работает без проблем, проблема возникает, когда я пытаюсь использовать вторую часть цикла.

Вот как выглядит мой код

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 ]

4 голосов
/ 23 января 2011

Я не уверен, правильно ли я понимаю, что вам нужно - вопрос очень запутанный.То, что вы ВИДЕТЕ, чтобы спросить:

  • У вас есть сложный вложенный 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

Проблема в XML-теге <Setup>FALSE</Setup>.Он не имеет подтегов, поэтому в хэше его значением будет скаляр, а не хеш.Для исправления необходимо проверить, что внутренний элемент действительно является хешем:

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 голосов
/ 23 января 2011

Вы можете перебрать хеш, используя 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";
}
...