我有一个perl脚本,它基本上是从XML生成JSON。这部分工作正常。但是在做了一些业务逻辑之后,我需要为JSON中的现有元素添加一个新的键值对。
我能够在JSON中插入一个全新的元素,但不能在输入JSON的现有元素中插入键值对。
以下是JSON示例:
{
"Person": {
"ID": "0",
"SchemaVersion": "1.0.8",
"Home": {
"ID": "ABC-XYZ",
"Laptop": {
"FileName": "/usr/temp/RPM_020515_.tar.gz"
},
"Location": {
"Number": "62",
"MaxSize": "0",
"Comment": { },
"SiteName": { }
},
"State": "Unknown"
}
}
}
现在在json上面我试图添加一个基于元素Laptop(Person-> Home-> Laptop)下的一些业务逻辑生成的新键值对。 (键值对示例:“Key”:“123456789”),所以新JSON看起来像这样:
{
"Person": {
"ID": "0",
"SchemaVersion": "1.0.8",
"Home": {
"ID": "ABC-XYZ",
"Laptop": {
"FileName": "/usr/temp/RPM_020515_.tar.gz",
"Key": "123456789"
},
"Location": {
"Number": "62",
"MaxSize": "0",
"Comment": { },
"SiteName": { }
},
"State": "Unknown"
}
}
}
我在perl代码中采用的方法是:
相同的Perl代码:(忽略任何缺少的使用语句,使脚本不那么复杂只是为了突出显示错误)
#!/usr/bin/perl
use strict;
use warnings FATAL => qw( all );
use Data::Dumper;
use JSON;
# get back the original JSON into a hashmap (key value pairs)
( $json is output of JSON generated from an XML file but for this example
please use the sample JSON i have mentioned above )
my $tempHash = decode_json($json);
# new key-value pair that needs to be added in the JSON ( in original code
it is being generated from business logic but in similar format )
%filedata = ('Key', 123456789);
# insert the fileKey now. Think about how to insert the file key here
push @{ $tempHash->{'Person'}->{'Home'}->{'Laptop'}}, $\%fileData;
my $newJSON = encode_json($tempHash);
上面的代码无法正常工作。 它实际上是通过创建新元素{'Person'} - > {'Home'} - > {'Laptop'}}来添加键值对,而不是在现有元素下添加它们(这是预期的行为)。
有人可以指出我正确的语法或任何其他建议表示赞赏。
我试过用非常简单的方式解释这个问题(原始代码现在变得非常复杂并且做了很多不同的事情)。让我知道是否需要更多细节,或者我需要更多信息来解决问题。
答案 0 :(得分:3)
而不是你的行
%filedata = ('Key', 123456789);
# insert the fileKey now. Think about how to insert the file key here
push @{ $tempHash->{'Person'}->{'Home'}->{'Laptop'}}, $\%fileData;
使用行
my ($key, $val) = ('Key', 123456789);
$tempHash->{'Person'}->{'Home'}->{'Laptop'}->{$key} = $val;
您甚至可以使用哈希切片将一堆值插入到一堆键中。
my %filedata = ( Key1 => 123, Key2 => 456 );
@{ $tempHash->{Person}{Home}{Laptop} }{keys %filedata} = values %filedata;
这只是更通用但繁琐的代码的专用版本
my @keys = qw(Key1 Key2);
my @values = (123, 456);
@{ $tempHash->{Person}{Home}{Laptop} }{@keys} = @values;
答案 1 :(得分:1)
直接设置键和值会更有意义。您的JSON的笔记本电脑部分不一个数组,因此您无法将元素推送到它上面:
use strict;
use warnings;
use Data::Dumper;
use JSON;
my $json;
{
local $/;
$json = from_json( <DATA> );
}
$json->{Person}->{Home}->{Laptop}->{Key} = 123456789;
print Dumper $json;
__DATA__
{
"Person": {
"ID": "0",
"SchemaVersion": "1.0.8",
"Home": {
"ID": "ABC-XYZ",
"Laptop": {
"FileName": "/usr/temp/RPM_020515_.tar.gz"
},
"Location": {
"Number": "62",
"MaxSize": "0",
"Comment": { },
"SiteName": { }
},
"State": "Unknown"
}
}
}
答案 2 :(得分:1)
我会用:
use strict;
use warnings;
use JSON;
use Hash::Merge qw(merge);
my $wantadd->{Person}->{Home}->{Laptop} = {
key => 123456,
some => 'data1',
other => 'data2',
deeper => {
deep1 => "deep1",
deep2 => "deep2",
},
};
my $json_str = do { local $/; <DATA> };
my $json = JSON->new();
my $tempHash = $json->decode($json_str);
my $newhash = merge($tempHash,$wantadd);
print $json->pretty->encode($newhash);
#or in compact form
print encode_json(merge(decode_json($json_str),$wantadd));
__DATA__
{
"Person" : {
"ID" : "0",
"SchemaVersion" : "1.0.8",
"Home" : {
"State" : "Unknown",
"Laptop" : {
"FileName" : "/usr/temp/RPM_020515_.tar.gz"
},
"Location" : {
"MaxSize" : "0",
"Comment" : {},
"SiteName" : {},
"Number" : "62"
},
"ID" : "ABC-XYZ"
}
}
}
打印:
{
"Person" : {
"ID" : "0",
"Home" : {
"ID" : "ABC-XYZ",
"Location" : {
"MaxSize" : "0",
"SiteName" : {},
"Number" : "62",
"Comment" : {}
},
"State" : "Unknown",
"Laptop" : {
"FileName" : "/usr/temp/RPM_020515_.tar.gz",
"key" : 123456,
"other" : "data2",
"deeper" : {
"deep1" : "deep1",
"deep2" : "deep2"
},
"some" : "data1"
}
},
"SchemaVersion" : "1.0.8"
}
}
{"Person":{"SchemaVersion":"1.0.8","Home":{"ID":"ABC-XYZ","Laptop":{"key":123456,"FileName":"/usr/temp/RPM_020515_.tar.gz","some":"data1","deeper":{"deep1":"deep1","deep2":"deep2"},"other":"data2"},"State":"Unknown","Location":{"MaxSize":"0","SiteName":{},"Number":"62","Comment":{}}},"ID":"0"}}
将新数据添加到所需位置。