【问题标题】:Directly access nested JSON data in perl?在 perl 中直接访问嵌套的 JSON 数据?
【发布时间】:2017-07-25 09:13:20
【问题描述】:

我不熟悉 Perl 的散列/引用语法,这让我的眼睛很难受。
我有以下 JSON:

{
  "Arg":"Custom_Light state alias protocol",
  "Results": [
  {
    "Name":"Custom_Light",
    "Internals": { },
    "Readings": {
      "protocol": { "Value":"V3", "Time":"2017-01-14 18:49:18" },
      "state": { "Value":"off", "Time":"2017-03-05 10:39:50" }
    },
    "Attributes": {      "alias": "Kitchen light" }
  }  ],
  "totalResultsReturned":1
}

如何直接获取 Reading > Protocol Value 和 Reading > state Value 以及 Attributes > Alias?

我正在使用默认的JSON 编码器/解码器,它工作得很好。使用 Dumper($json) 我得到了所有的 JSON,但我不知道如何在不使用 foreach 的情况下直接访问它。

我尝试了以下方法:

my $json = from_json( $readout, { utf8  => 1 } );
print "No. Entries:", scalar(keys($json)); #works, returns 3
my @results = %$json{Results};
Dumper(@results[1]); #I get the Results array

从这里开始已经很丑了。 %$ 在那里做什么?我以为我可以做类似print ${ $json->{'Results'}->[1] }{'Readings'}; 的事情,但这让我无处可去。

给我智慧。如何直接访问协议值?如何直接访问状态值?最后,如何获取别名属性?


我不知道我在做什么,但我正在使用my $test = %{${%$json{Results}}[0]}{Name}; #I get "Custom_Light", nice。这是随机抛出大量奇怪的%$ 的方法吗?

【问题讨论】:

  • 要获取Value 字段,您可以编写:$json->{Results}[0]{Readings}{state}{Value}。并获得alias$json->{Results}[0]{Attributes}{alias}
  • 是的!这看起来很漂亮。把它变成一个答案,这样我就可以给你一些爱。
  • %$ 在那里做什么?”我想知道,但我以为是你写的!
  • 我确实写了它并且它有效。在论坛中对如何在 perl 中“取消引用”(无论如何,我知道强制转换)哈希表进行一些调查后,发现 %$。您的解决方案看起来好多了

标签: arrays json perl hash


【解决方案1】:

你想要

$json->{Results}[0]{Readings}{protocol}{Value}
$json->{Results}[0]{Readings}{state}{Value}
$json->{Results}[0]{Attributes}{alias}

但是,由于 Results 项目是一个数组,您可能想要遍历它的所有元素,尽管在这种情况下只有一个元素

我发现一次将一级引用提取到临时变量中很有用。它看起来像这样

my $results = $json->{Results};

for my $result ( @$results ) {

    my $readings   = $result->{Readings};
    my $attributes = $result->{Attributes};

    printf "Protocol: %s\n", $readings->{protocol}{Value};
    printf "State:    %s\n", $readings->{state}{Value};
    printf "Alias:    %s\n", $attributes->{alias};
    print "\n";
}

【讨论】:

  • 感谢您将结果视为数组!
【解决方案2】:

看看perlreftutperldscperlref,它将帮助您了解如何在 Perl 中访问深度嵌套的结构。

print "No. Entries:", scalar(keys($json)); #works,返回 3

实际上,这将不再有效。在标量上使用 keys 是 Perl 5.14 中添加的一项实验性功能,它允许 eachkeyspushpopshiftspliceunshift 和 @98765433用标量参数调用。这个实验被认为是不成功的,并在 5.23 中被删除。另见Experimental values on scalar is now forbidden。因此,您应该在应用 keys 之前取消引用哈希引用 $json

print "No. Entries:", scalar keys %$json;

perlref 中所述,%$ref 取消引用哈希引用$ref。接下来,让我们看看这一行:

我的@results = %$json{结果};

这实际上首先创建了一个新的(匿名)哈希( Result => $json->{Result} ),然后将其分配给@results,从而生成@result = ( 'Result', $json->{Result} )。这就是为什么您现在可以将$json->{Result}[0] 称为$result[1]

但这是晦涩难懂的编码,可能也不是有意的。所以回到你的问题,得到Value 字段,你可以写:

my $value = $json->{Results}[0]{Readings}{state}{Value};

并获得alias 字段:

my $alias = $json->{Results}[0]{Attributes}{alias};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-30
    • 2021-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多