Разбор JSON данных в Perl - PullRequest
       1

Разбор JSON данных в Perl

0 голосов
/ 06 февраля 2020

Я анализирую JSON данных, которые находятся в .json файле. Здесь у меня есть 2 формата JSON файлов данных.

Я мог бы проанализировать первый JSON файл - файл показан ниже:

file1.json

{
  "sequence" : [ {
    "type" : "type_value",
     "attribute" : {
      "att1" : "att1_val",
      "att2" : "att2_val",
      "att3" : "att3_val",
      "att_id" : "1"
    }
  } ],
  "current" : 0,
  "next" : 1
}

Вот мой сценарий:

#/usr/lib/perl
use strict;
use warnings;
use Data::Dumper;

use JSON;

my $filename = $ARGV[0]; #Pass json file as an argument
print "FILE:$filename\n";

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};

my %Hash;

for my $element (@$aref) {
    my $a = $element->{attribute};
    next if(!$a);

    my $aNo = $a->{att_id};
    $Hash{$aNo}{'att1'}     = $a->{att1};
    $Hash{$aNo}{'att2'}     = $a->{att2};
    $Hash{$aNo}{'att3'}     = $a->{att3};
}

print Dumper \%Hash;

Все сохраняется в %Hash, и когда я печатаю Dumper из %Hash, я получаю следующий результат.

$VAR1 = {
          '1' => {
                   'att1' => 'att1_val',
                   'att2' => 'att2_val',
                   'att3' => 'att3_val'
                 }
        };

Но когда я анализирую второй набор файла JSON, я получаю пустой ха sh с помощью вышеуказанного скрипта. Вывод:

$VAR1 = {};

Вот файл JSON - file2.json

{
  "sequence" : [ {
    "type" : "loop",
    "quantity" : 8,
    "currentIteration" : 0,
    "sequence" : [ {
      "type" : "type_value",
      "attribute" : {
        "att1" : "att1_val",
        "att2" : "att2_val",
        "att3" : "att3_val",
        "att_id" : "1"
      }
    } ]
  } ]
}

Мы можем видеть два sequence в приведенном выше JSON файле данных, который вызывает проблема. Может кто-нибудь сказать мне, что мне не хватает в сценарии для анализа file2.json.

Ответы [ 2 ]

2 голосов
/ 06 февраля 2020

Одной из возможностей может быть проверка поля type для различия между двумя форматами файлов:

# [...]
for my $element (@$aref) {
    if ( $element->{type} eq "loop" ) {
        my $aref2 = $element->{sequence};
        for my $element2 ( @$aref2 ) {
            get_attrs( $element2, \%Hash );
        }
    }
    else {
        get_attrs( $element, \%Hash );
    }
}

sub get_attrs {
    my ( $element, $hash ) = @_;

    my $a = $element->{attribute};
    return if(!$a);

    my $aNo = $a->{att_id};
    $hash->{$aNo}{'att1'}     = $a->{att1};
    $hash->{$aNo}{'att2'}     = $a->{att2};
    $hash->{$aNo}{'att3'}     = $a->{att3};
}
0 голосов
/ 06 февраля 2020

Пожалуйста, смотрите следующий код, если он соответствует вашим требованиям

#!/usr/bin/env perl
#
# vim: ai:sw=4:ts=4
#

use strict;
use warnings;
use feature 'say';

use Data::Dumper;
use JSON;

my $debug = 0;          # debug flag

my $filename = shift;   # Pass json file as an argument

say "FILE: $filename";

open(my $json_fh, "<:encoding(UTF-8)", $filename)
    or die("Can't open \$filename\": $!\n");

my $json_data = do { local $/; <$json_fh> };

close $json_fh;

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

say Dumper($data) if $debug;

my $data_ref;
my %Hash;

$data_ref = $data->{sequence}[0]{attribute}
            if $filename eq 'file1.json';
$data_ref = $data->{sequence}[0]{sequence}[0]{attribute}
            if $filename eq 'file2.json';

say Dumper($data_ref) if $debug;

my @fields = qw/att1 att2 att3/;
my $aNo = $data_ref->{att_id};
my %data_hash;

@data_hash{@fields} = $data_ref->{@fields};
$Hash{$aNo} = \%data_hash;

say Dumper(\%Hash);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...