【问题标题】:parsing json file using perl使用perl解析json文件
【发布时间】:2013-03-17 05:07:25
【问题描述】:

我正在尝试在 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};

但我没有得到任何输出。

谁能告诉我怎么了?

【问题讨论】:

标签: json perl


【解决方案1】:

您的 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-&gt;{name} 应该应用于 .json 文件中数组的所有成员,而不是 json 本身。所以你需要先遍历它们

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

JSON 可以描述复杂的数据结构,所以当你将它解析成 Perl 时,你也会得到一个复杂的数据结构。尝试先看看使用Data::DumperData::PrinterData::TreeDumper的数据结构

【讨论】:

【解决方案2】:

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

use strict; 
use warnings;

-- 他们会告诉你哪里出了问题。在这种情况下,您正在打印一个未定义的值$data-&gt;{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
}

【讨论】:

  • 这是一个替代方案 map { print $_-&gt;{name}; } @{$data-&gt;{data}}; 。或者你可以print join(",",(map{ $_-&gt;{name}} @{$data-&gt;{data}})); 虽然它仍然是一个循环。为什么需要非循环解决方案?
猜你喜欢
  • 2014-02-08
  • 1970-01-01
  • 2016-07-31
  • 1970-01-01
  • 2017-10-28
  • 2015-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多