在现有的json元素中添加新的键值对

时间:2015-03-17 20:29:42

标签: json perl hashmap

我有一个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代码中采用的方法是:

  1. 首先将JSON转换为哈希映射
  2. 尝试添加新元素(这是问题出现的地方,我可以添加一个全新的元素,但不能在现有元素中添加键值对)
  3. 将哈希映射转换回JSON。
  4. 相同的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'}}来添加键值对,而不是在现有元素下添加它们(这是预期的行为)。

    有人可以指出我正确的语法或任何其他建议表示赞赏。

    我试过用非常简单的方式解释这个问题(原始代码现在变得非常复杂并且做了很多不同的事情)。让我知道是否需要更多细节,或者我需要更多信息来解决问题。

3 个答案:

答案 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"}}

将新数据添加到所需位置。