排除“伪哈希值已被弃用”的问题使用 xml 模块时

发布于 2024-12-08 03:21:43 字数 4241 浏览 0 评论 0原文

我刚刚学习如何使用 perl 哈希并在 perl 中遇到了此消息。我使用 XML::Simple 解析 xml 输出,并使用 exists 检查哈希键。

消息: 伪哈希在 ./h2.pl 第 53 行已弃用。 参数“\x{2f}\x{70}...”在 ./h2.pl 第 53 行中的存在中不是数字。 在 ./h2.pl 第 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>

I am just learning how to use perl hashes and ran into this message in perl. I am using XML::Simple to parse xml output and using exists to check on the hash keys.

Message:
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.

I had the script working earlier with one test directory and then executed the script on another directory for testing when I got this message. How do I resolve/workaround this?

Code that the error references:

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 );

Working test case, data structure looks like this:

$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:

Data structure with seeing error:

$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'
                    },

Test xml file:

<?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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

污味仙女 2024-12-15 03:21:43

“Pseudo-hashes are deprecated”错误意味着您正在尝试将数组作为哈希访问,这意味着 $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;
}

The "Pseudo-hashes are deprecated" error means you're trying to access an array as a hash, which means that either $data->{file} or $data->{file}{path} is an arrayref.

You can check the data type by using print ref $data->{file}. The Data::Dumper module may also help you to see what is in your data structure (perhaps while setting $Data::Dumper::Maxdepth = N to limit the dump to N number of levels if the structure is big).

UPDATE

Now that you are using ForceArray, $data->{file} should always point to an arrayref, which may possibly have multiple references to path. Here is a modified segment of your code to handle that. But note that the logic of the if-then-exit conditions may have to change.

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;
}
知你几分 2024-12-15 03:21:43

使用 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)]);

When using XML::Simple, the ForceArray option is one of the most important to understand, especially in cases when your input data has nested elements that can occur 1 or more times. For example:

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);
}

Output:

$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'
  }
};

By activating the ForceArray option, you can direct XML::Simple to produce consistent data structures that always use the intermediate array reference, even when there is only 1 of a particular nested element. You can activate the option globally or for specific tags, as illustrated here:

my $data = XMLin($xs, ForceArray => 1                );  # Globally.
my $data = XMLin($xs, ForceArray => [qw(name foo bar)]);
月棠 2024-12-15 03:21:43

首先,我建议您使用 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 ...

First, I recommend that you use ForceArray => [qw( file )] as previously discussed. That will cause an array to be returned for file, whether there's one or more file element. This is easier to handle than having two possible formats.

As I previously indicated, the problem is that you made no provision for looping over multiple file elements. You said you wanted to exit if the file doesn't exist, so that means you want

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 ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文