【问题标题】:Perl add content to JSON data after processingPerl 处理后向 JSON 数据添加内容
【发布时间】:2020-07-21 18:43:27
【问题描述】:

我有一个 json 文件,我正在使用 perl JSON 模块处理它。

处理完后,我想在其中插入一些内容。

这是我的输入 json 文件:

{
  "sequence" : [ 
  {
    "type" : "event",
    "attribute" : {     
      "contentText" : "Test Content",
      "contentNumber" : "11"
    }
  } 
  ],
  "current" : 0,
  "next" : 1
}

下面是我的脚本:

#!/usr/bin/perl

use strict;
use warnings;

use JSON;
use Data::Dumper;

my $needed = 2;
my $filename = "test_file.json";

my $json_text = do {
            open(my $json_fh, "<:encoding(UTF-8)", $filename)
            or die("Can't open \$filename\": $!\n");
            local $/;
            <$json_fh>
    };

my $json = JSON->new;
my $data = $json->decode($json_text);

my $aref = $data->{sequence};

print Dumper($aref);

my $number;

for my $element (@$aref) {
    $number = $element->{attribute}->{contentNumber}."\n";
}

print "Number:$number\n";

my $total = $number + $needed;

foreach my $each_number ($number+1..$total){
    print $each_number."\n";
}

print Dumper $data;

所以我在这里需要的是从给定的 json 文件中获取 contentNumber 并将值递增 1 直到提到 $needed 并形成一个新的 json 文件。

最后它应该形成 JSON 文件,其内容应如下所示: 无论$needed变量值是什么,很多时候json应该形成包括初始数据在内的数据。

{
  "sequence" : [ 
  {
    "type" : "event",
    "attribute" : {     
      "contentText" : "Test Content",
      "contentNumber" : "11"
    }
  },
  {
    "type" : "event",
    "attribute" : {     
      "contentText" : "Test Content",
      "contentNumber" : "12"
    }
  },
  {
    "type" : "event",
    "attribute" : {     
      "contentText" : "Test Content",
      "contentNumber" : "13"
    }
  }
  ],
  "current" : 0,
  "next" : 1
}

我想在foreach 循环中推送数据。但不知道我们如何将它放在数据对象中,它应该给我一个 json 格式的输出。

【问题讨论】:

    标签: json perl


    【解决方案1】:

    从所需的输出看来,您需要 sequence 数组中的 hashref。然后你需要将$needed 的副本数量添加到该数组中,contentNumber 在每个中递增。 (我无法将其与显示的代码相协调,我将使用所需的输出,这似乎很清楚。)

    不要忘记副本必须是副本;这里我使用dclone from Storable

    use Storable qw(dclone);
    
    ...
    
    my $seq_href = dclone( $data->{sequence}[0] );
    
    for (1..$needed) { 
        ++$seq_href->{attribute}{contentNumber};
        push @{$data->{sequence}}, dclone( $seq_href );
    }
    
    my $new_json_string = $json->encode($data);  # then write it to file
    

    这会在我的测试中生成所需的输出 JSON。


    包含引用的变量或数据结构不能仅通过赋值复制到新的独立结构中

    my @copy = @ary;   # oups ... any references in there?
    

    问题在于,当@ary 中的引用元素被复制到@copy 中时,@copy 中的那些元素作为相同的引用,指向与@ary 中的元素相同的内存位置!所以@copy@ary 绝不是独立的——它们共享数据。

    有时这可能是需要的,但如果我们需要一个独立的副本,就像在这个问题中一样,那么我们需要一直遵循这些引用并实际复制数据,以便复制的结构确实具有自己的数据。当然也有模块可以做到这一点。

    根据定义,复杂(嵌套)数据结构具有元素引用,因此我们当然无法通过一个顶级分配获得独立副本。

    这是对潜在的偷偷摸摸和微妙的错误的非常简短的描述。我建议阅读更多内容。出现的一种资源是Effective Perler article

    【讨论】:

    • 是的,我可以在我的代码中看到Dumper($data) 中的数据。那么我怎样才能把它放在.json 文件中呢?我可以直接将其转储到 json 文件中吗?有什么建议吗?
    • @vinodk89 啊,对,那个(在问题中没有注意到)--- 使用相同的模块转换回 JSON,然后将其写为文件。我会添加这个...
    • 是的@zdim。我已经对$data 中的数据进行了编码并写入了一个文件。这行得通!谢谢。
    猜你喜欢
    • 2017-03-01
    • 2018-08-05
    • 1970-01-01
    • 2017-07-09
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多