Perl добавить содержимое к JSON данным после обработки - PullRequest
2 голосов
/ 09 апреля 2020

У меня есть файл 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;

Так что мне здесь нужно получить contentNumber из данного json файл и значение приращения от 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
}

Я думал о том, чтобы sh данные в foreach l oop. Но не знаю, как мы можем поместить его в объект данных, который должен дать мне вывод в формате json.

1 Ответ

5 голосов
/ 09 апреля 2020

Из требуемого вывода видно, что вам нужен хеш-адрес, который находится в массиве sequence. Затем вам нужно добавить $needed количество его копий в этот массив, с увеличением contentNumber в каждом. (Я не могу согласовать это с показанным кодом, и я go получу желаемый результат, который кажется ясным.)

Не забывайте, что копии должны быть глубокие копии; здесь я использую dclone из Для хранения .

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 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...