устранение неполадок "псевдо-хэши устарели" при использовании модуля xml - PullRequest
3 голосов
/ 01 октября 2011

Я только учусь использовать хеш perl и наткнулся на это сообщение в perl.Я использую XML::Simple для анализа xml-вывода и exists для проверки ключей хеш-функции.

Сообщение: Pseudo-hashes are deprecated at ./h2.pl line 53. Argument "\x{2f}\x{70}..." isn't numeric in exists at ./h2.pl line 53. Bad index while coercing array into hash at ./h2.pl line 53.

У меня был скрипт работал ранее с одним тестовым каталогом, а затем выполнил скрипт в другом каталоге для тестирования, когда я получил это сообщение.Как мне разрешить / обойти это?

Код, на который ссылается ошибка:

use strict;
use warnings;
use XML::Simple;
use Data::Dumper;

#my $data = XMLin($xml);
my $data = XMLin($xml, ForceArray => [qw (file) ]);
my $size=0;

if (exists $data->{class}
       and $data->{class}=~ /FileNotFound/) {
        print "The directory: $Path does not exist\n";
        exit;
          } elsif (exists $data->{file}->{path}
                      and $data->{file}->{path} =~/test-out-00/) {
                    $size=$data->{file}->{size};
                       if ($size < 1024000) {
                          print "FILE SIZE:$size BYTES\n";
                          exit;
                       }
          } else {
            exit;
}

print Dumper( $data );

Рабочий тестовый пример, структура данных выглядит следующим образом:

$VAR1 = {
              'recursive' => 'no',
              'version' => '0.20.202.1.1101050227',
              'time' => '2011-09-30T02:49:39+0000',
              'filter' => '.*',
              'file' => {
                        'owner' => 'test_act',
                        'replication' => '3',
                        'blocksize' => '134217728',
                        'permission' => '-rw-------',
                        'path' => '/source/feeds/customer/test/test-out-00',
                        'modified' => '2011-09-30T02:48:41+0000',
                        'size' => '135860644',
                        'group' => '',
                        'accesstime' => '2011-09-30T02:48:41+0000'
                     'modified' => '2011-09-30T02:48:41+0000'
                   },
      'exclude' => ''
    };
recursive:no
version:0.20.202.1.1101050227
time:2011-10-01T07:06:16+0000
filter:.*
file:HASH(0x84c83ec)
path:/source/feeds/customer/test
directory:HASH(0x84c75d8)
exclude:

Структура данных с ошибкой просмотра:

$VAR1 = {
          'recursive' => 'no',
          'version' => '0.20.202.1.1101050227',
          'time' => '2011-10-03T04:49:36+0000',
          'filter' => '.*',
          'file' => [
                    {
                      'owner' => 'test_act',
                      'replication' => '3',
                      'blocksize' => '134217728',
                      'permission' => '-rw-------',
                      'path' => '/source/feeds/customer/test/20110531/test-out-00',
                      'modified' => '2011-10-03T04:47:46+0000',
                      'size' => '121406618',
                      'group' => 'feeds',
                      'accesstime' => '2011-10-03T04:47:46+0000'
                    },

Тестовый XML-файл:

<?xml version="1.0" encoding="UTF-8"?><listing time="2011-10-03T04:49:36+0000" recursive="no" path="/source/feeds/customer/test/20110531" exclude="" filter=".*" version="0.20.202.1.1101050227"><directory path="/source/feeds/customer/test/20110531" modified="2011-10-03T04:48:19+0000" accesstime="1970-01-01T00:00:00+0000" permission="drwx------" owner="test_act" group="feeds"/><file path="/source/feeds/customer/test/20110531/test-out-00" modified="2011-10-03T04:47:46+0000" accesstime="2011-10-03T04:47:46+0000" size="121406618" replication="3" blocksize="134217728" permission="-rw-------" owner="test_act" group="feeds"/><file path="/source/feeds/customer/test/20110531/test-out-01" modified="2011-10-03T04:48:04+0000" accesstime="2011-10-03T04:48:04+0000" size="127528522" replication="3" blocksize="134217728" permission="-rw-------" owner="test_act" group="feeds"/><file path="/source/feeds/customer/test/20110531/test-out-02" modified="2011-10-03T04:48:19+0000" accesstime="2011-10-03T04:48:19+0000" size="125452919" replication="3" blocksize="134217728" permission="-rw-------" owner="test_act" group="feeds"/></listing>

Ответы [ 3 ]

5 голосов
/ 01 октября 2011

Ошибка «Псевдо-хэши устарела» означает, что вы пытаетесь получить доступ к массиву как к хешу, что означает, что $data->{file} или $data->{file}{path} - это ссылка на массив.

Вы можете проверитьтип данных с помощью print ref $data->{file}.Модуль Data::Dumper может также помочь вам увидеть, что находится в вашей структуре данных (возможно, при установке $Data::Dumper::Maxdepth = N для ограничения дампа числом уровней N, если структура большая).

ОБНОВЛЕНИЕ

Теперь, когда вы используете ForceArray, $data->{file} всегда должен указывать на arrayref, который может иметь несколько ссылок на path.Вот модифицированный сегмент вашего кода, чтобы справиться с этим.Но учтите, что логика условий if-then-exit может измениться.

if (defined $data->{class} and $data->{class}=~ /FileNotFound/) {
    print "The directory: $Path does not exist\n";
    exit;
}

exit if ! defined $data->{file};

# filter the list for the first file entry named test-out-00
my ( $file ) = grep { 
    defined $_->{path} && $_->{path} =~ /test-out-00/ 
} @{ $data->{file} };

exit if ! defined $file;

$size = $file->{size};
if ($size < 1024000) {
    print "FILE SIZE:$size BYTES\n";
    exit;
}
2 голосов
/ 01 октября 2011

При использовании XML :: Simple параметр ForceArray является одним из наиболее важных для понимания, особенно в тех случаях, когда ваши входные данные содержат вложенные элементы, которые могут встречаться 1 или более раз.Например:

use XML::Simple;
use Data::Dumper;

my @xml_snippets = (
    '<opt> <name x="3" y="4">B</name> <name x="5" y="6">C</name> </opt>',
    '<opt> <name x="1" y="2">A</name>                            </opt>',
);

for my $xs (@xml_snippets){
    my $data = XMLin($xs, ForceArray => 0);
    print Dumper($data);
}

Вывод:

$VAR1 = {
  'name' => [      # Array ref because there are 2 <name> elements.
    {
      'y' => '4',
      'content' => 'B',
      'x' => '3'
    },
    {
      'y' => '6',
      'content' => 'C',
      'x' => '5'
    }
  ]
};
$VAR1 = {
  'name' => {      # No intermediate array ref.
    'y' => '2',
    'content' => 'A',
    'x' => '1'
  }
};

Активировав опцию ForceArray, вы можете указать XML :: Simple для создания согласованных структур данных, которыевсегда используйте промежуточную ссылку на массив, даже если есть только 1 из конкретного вложенного элемента.Вы можете активировать опцию глобально или для определенных тегов, как показано здесь:

my $data = XMLin($xs, ForceArray => 1                );  # Globally.
my $data = XMLin($xs, ForceArray => [qw(name foo bar)]);
0 голосов
/ 03 октября 2011

Во-первых, я рекомендую использовать ForceArray => [qw( file )], как обсуждалось ранее. Это приведет к тому, что массив будет возвращен для file, независимо от того, есть ли один или несколько элементов file. С этим легче справиться, чем с двумя возможными форматами.

Как я уже указывал, проблема в том, что вы не предусмотрели зацикливание на нескольких file элементах. Вы сказали, что хотите выйти, если файл не существует, а это значит, что вы хотите

my $found;
for my $file (@{ $data->{file} }) {
   if ($file->{path} =~ m{/test-out-00\z}) {
      $found = $file;
      last;
   }
}

die("Test file not found\n") if !$found;

... do something with file data in $found ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...