Perl,JSON解析值不正确

时间:2016-09-16 09:39:47

标签: json perl

我正在解析存储在数据库中的JSON字符串。

{"name":"simon", "age":"23", "height":"tall"}

我正在拉数据,然后解码。运行下面的代码时,我收到了奇怪的“HASH”值。

use JSON;

$data = decode_json($row->{'address'});
for my $key (keys %$data){
       if($data->{$key} ne ''){
               $XML .= "      <$key>$data->{$key}</$key>";
       }
}

// Returns data like so 

<company_type>HASH(0x27dbac0)</company_type>
<county>HASH(0x27db7c0)</county>
<address1>HASH(0x27dba90)</address1>
<company_name>HASH(0x27db808)</company_name>

当我有这样的数据集时会发生错误:

{"name":"", "age":{}, "height":{}}

我不明白为什么JSON / Arrays / Hashes必须如此难以在Perl中使用。我错过了什么?

1 个答案:

答案 0 :(得分:5)

您正在处理平面哈希,而您的数据实际上具有另一个嵌套的hashref。在行

{ "name":"", "age":{}, "height":{} }

{}可能意味着“没有”但实际上是JSON "object",嵌套数据的下一级(确实是空的)。在Perl中,我们得到了一个hashref,这就是你的代码打印的内容。

JSON的另一个支柱是“数组”,在Perl中我们得到一个arrayref。这就是 - decode_json为我们提供了顶级hashref,当取消引入哈希时,它可能包含进一步的哈希或数组引用作为值。如果使用Data::Dumper打印整个结构,您会看到。

为了协商这个问题,我们每次都要测试一下参考。由于解除引用的散列或数组可能包含更多级别(更多引用),因此我们需要使用递归例程(请参阅this post示例)或复杂数据结构的模块。但是对于第一级

for my $key (keys %$data)
{
    next if $data->{$key} eq '';

    my $ref_type = ref $data->{$key};

    # if $data->{key} is not a reference ref() returns an empty string (false)
    if (not $ref_type) {
        $XML .= "      <$key>$data->{$key}</$key>";
    }
    elsif ($ref_type eq 'HASH') {
        # hashref,  unpack and parse. it may contain references
        say "$_ => $data->{$key}{$_}" for keys %{ $data->{$key} };
    }
    elsif ($ref_type eq 'ARRAY') {
        # arrayref, unpack and parse. it may contain references
        say "@{$data->{$key}}";
    }
    else { say "Reference is to type: $ref_type" }
}

如果ref的参数不是引用(但是字符串或数字),ref将返回一个空字符串,其值为false,即具有纯数据时。否则返回引用所针对的类型。来自JSON的广告可以是HASHARRAY。这就是嵌套的完成方式。

在显示的示例中,您将运行到hashref中。由于您显示的那些是空的,您可以放弃它们,并且特定示例的代码可以大大减少一个语句。但是,我会留下其他测试。这也应该与发布的示例一致。