使用Perl编码复杂的JSON结构

Tom*_*Tom 3 perl json

我想使用MySQL将MySQL查询的结果编码为JSON字符串JSON::XS.JSON字符串需要如下所示

{
    "database" : "dbname"
    "retentionPolicy" : "mytest",
    "tags" : {
        "type" : "generate",
        "location" : "total",
        "source" : "ehz"
    },
    "points" : [{
            "precision" : "ms",
            "timestamp" : "ts1",
            "name" : "power",
            "values" : {
                "value" : "val1"
            }
        }, {
            "precision" : "ms",
            "timestamp" : "ts2",
            "name" : "power",
            "values" : {
                "value" : "val2"
            }
        }, {
            "precision" : "ms",
            "timestamp" : "ts3",
            "name" : "power",
            "values" : {
                "value" : "val3"
            }
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

points每个点values元素的数组给我带来了巨大的麻烦.

这是生成JSON的代码块

my %json_body = (
                'database' => $db_name,
                'retentionPolicy' => $retention,
                'tags' => {
                    'source' => $metric_source,
                    'type' => $metric_type,
                    'location' => $metric_location
                }
                );

# loop through mysql result
while ( ($timestamp, $value) = $query->fetchrow_array() ) {
    my %json_point1 = (
                        'name' => $series_name,
                        'timestamp' => ($timestamp * 1),
                        'precision' => "ms"
                      );
    %json_point2 = ('value' => $value); 
    %json_values = (%json_point1, 'values' => \%json_point2); 
    push(@all_values, \%json_values);       
}
$query->finish();

# Encode json
my %json_data = (%json_body, "points" => \@all_values);
$influx_json = encode_json(\%json_data);
Run Code Online (Sandbox Code Playgroud)

我认为这条线push(@all_values, \%json_values)是我的问题.如果我%json_data作为哈希引用传递,则仅while保留循环中的最后一个值.如果我%json_values直接使用,编码的JSON会搞乱,因为它会丢失结构.

任何提示都将不胜感激.请耐心等待:这个数组和哈希引用已经让我的头脑爆炸了.

Sob*_*que 7

我敢肯定你的问题会因为您使用的是全局范围的哈希%json_point%json_point2.你看,它的根源是 - 你根本没有得到哈希列表.您将获得哈希引用列表.

所以这里的问题是 - 当你将哈希的引用推入时@all_values- 你每次都推送相同的引用.但是你要覆盖你引用的哈希的内容.

试试这个:

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my %hash_thing;
my @all_values; 

for ( 1..3 ) {
   %hash_thing = ( "test" => $_ );
   push ( @all_values, \%hash_thing ) ; 
}

print join ( "\n", @all_values );
print Dumper \@all_values;
Run Code Online (Sandbox Code Playgroud)

而且你会看到你有3次相同的'价值':

HASH(0x74478c)
HASH(0x74478c)
HASH(0x74478c)
Run Code Online (Sandbox Code Playgroud)

所以如果你转储它,那么当然 - 你没有得到正确的数组 - 所以你的编码JSON也不起作用.

$VAR1 = [
          {
            'test' => 3
          },
          $VAR1->[0],
          $VAR1->[0]
        ];
Run Code Online (Sandbox Code Playgroud)

最简单的解决方法是使用my将哈希范围限定为循环.(然后打开use strict;,use warnings如果你还没有.)

或者,您可以使用这样的哈希引用:

my @all_values; 
my $hash_ref;

for ( 1..3 ) {
   $hash_ref =  { "test" => $_ };
   push ( @all_values, $hash_ref ) ; 
}

print @all_values;
print Dumper \@all_values;
Run Code Online (Sandbox Code Playgroud)

因为$hash_ref它是标量,并且它是对匿名散列的引用,所以它可以通过值而不是通过引用插入到数组中.