5

我正在尝试在 perl 中解析一个 json 文件。我想提取键“名称”及其对应的值。我的文件看起来像这样

{
 "data":[
    {
        "name":"ABC",
        "id":"123",
    },
    {
        "name":"PQR",
        "id":"456",
    },
    {
        "name":"XYZ",
        "id":"789",
    }
]
}

我正在尝试使用以下代码:

#/usr/lib/perl
use lib qw( ..);
use LWP::Simple;
use JSON;
my $filename = '/file.txt';
my $data;
if (open (my $json_str, $filename))
{
  local $/ = undef;
  my $json = JSON->new;
  $data = $json->decode(<$json_str>);
  close($json_stream);
}
print $data->{name};

但我没有得到任何输出。

谁能告诉我有什么问题?

4

2 回答 2

24

您的 json 文件无效。

第 5,10,15 行不应以逗号结尾,因为这是这些哈希的最后一个键/值对。

修复该问题后,这是您的代码版本,可为您提供预期结果:

#/usr/lib/perl
use strict;
use warnings;

use lib qw(..);

use JSON qw( );

my $filename = 'file.txt';

my $json_text = do {
   open(my $json_fh, "<:encoding(UTF-8)", $filename)
      or die("Can't open \"$filename\": $!\n");
   local $/;
   <$json_fh>
};

my $json = JSON->new;
my $data = $json->decode($json_text);

for ( @{$data->{data}} ) {
   print $_->{name}."\n";
}

一些问题:

  • 您正在使用$json_stream$json_str。您打算$json_stream在所有地方使用来表示文件句柄
  • $data->{name}应该应用于 .json 文件中数组的所有成员,而不是 json 本身。所以你需要先遍历它们

调试时,请确保您的 json 有效。通过jsonlint.com或cpan 的JSON::XS附带的json_xs实用程序。

JSON 可以描述复杂的数据结构,因此当您将其解析为 Perl 时,您也会得到一个复杂的数据结构。尝试首先使用Data::DumperData::PrinterData::TreeDumper查看数据结构

于 2013-03-27T07:09:55.013 回答
5

除了在 JSON 字符串中有一个额外的逗号之外,您还没有引用正确的值。始终使用

use strict; 
use warnings;

——他们会告诉你出了什么问题。在这种情况下,您正在打印一个未定义的值$data->{name},一个尚未分配值的变量。如果您在其中打印解码的结构,Data::Dumper则如下所示:

$VAR1 = {
          'data' => [
                      {
                        'name' => 'ABC',
                        'id' => '123'
                      },
                      {
                        'name' => 'PQR',
                        'id' => '456'
                      },
                      {
                        'name' => 'XYZ',
                        'id' => '789'
                      }
                    ]
        };

正如你所看到的,$data它实际上是一个哈希引用,其中第一个也是唯一一个键被调用'data',它的值是一个包含三个元素的数组,每个元素都包含一个哈希引用。因此,为了打印这些元素,您可以执行以下操作:

print $data->{data}[0]{name};   # prints ABC

my $aref = $data->{data};
for my $element (@$aref) {
    print $element->{name};     # prints ABC, PQR, XYZ
}
于 2013-03-27T07:23:07.797 回答