如何使用perl将JSON文件转换为定界文件。

时间:2018-09-27 15:00:10

标签: json perl

#/usr/lib/perl

use lib qw(..);
use JSON qw( );

open json_fh, "<$ARGV[0]" or die "Couldn't open file $ARGV[0]!\n";
open csv_fh, ">$ARGV[1]" or die "Couldn't open file $ARGV[1]!\n";

@json_text =<json_fh>;
close json_fh;
foreach $json_text( @json_text )
{
    chomp $json_text;
    $json = JSON->new;
    $data = $json->decode($json_text);

    $id=$data->{_id};
    @lines=@{$data->{accounts}};
    foreach $line ( @lines )
    {
        $accountNumber = $line->{accountNumber};
        $accountType = $line->{accountType};
        $cardType = $line->{cardType};
        $cardSubType = $line->{cardSubType};
        $protectionMethod = $line->{protectionMethod};
        $protectionSource = $line->{protectionSource};
        $expirationDate = $line->{expirationDate};
        $nameOnAccount = $line->{nameOnAccount};
        $cardStatus = $line->{cardStatus};
        $cardHolderType = $line->{cardHolderType};
        $createdBy = $line->{createdBy};
        $addressId = $line->{addressId};
        $productType = $line->{productType};
        $isDefaultAccount = $line->{isDefaultAccount};

        #Write to the file in delimited file format
        print csv_fh "$id|$accountNumber|$accountType|$cardType|$cardSubType|$protectionMethod|$protectionSource|$expirationDate|$nameOnAccount|$cardStatus|$cardHolderType|$createdBy|$addressId|$productType|$isDefaultAccount\n";
    }
}
close csv_fh;

这是我创建的一个perl脚本,用于将JSON文件转换为定界文件(如果元素名称已知)。

任何人都可以帮助我修改代码,以便在元素名称未知的情况下完成此转换。

2 个答案:

答案 0 :(得分:2)

假设每个帐户都具有相同的字段(否则就没有意义了),您可以使用以下内容:

my $json_parser = JSON->new;

my @headers;
for my $json_doc (@json_docs) {
   my $data = $json_parser->decode($json_doc);

   my $id = $data->{_id};
   for my $account (@{ $data->{accounts} }) {
      if (!@headers) {
         @headers = sort keys %$account;
         say join "|", 'id', @headers;
      }

      say join "|", $id, @$account{@headers};
   }
}

答案 1 :(得分:0)

您没有提供示例输入文件,所以我猜它是这样的:

{ "accounts": [ { "_id": "1", "accountNumber": "99999", "accountType": "acctTypeA", "cardType": "cardTypeA", "cardSubType": "cardSubTypeA", "protectionMethod": "protectionMethodA", "protectionSource": "protectionSourceA", "expirationDate": "2020-09", "nameOnAccount": "First Last", "cardStatus": "OK", "cardHolderType": "CHTypeA", "createdBy": "userX", "addressId": "444", "productType": "prodTypeA", "isDefaultAccount": "1", "optional": "OptA" } ] }

您非常接近,但是通常整个文件都是JSON记录,因此您不会逐行循环,而是创建一个表示整个文件的数据结构(hashref)(即,您只需要$ json->每个文件解码一次)。

此外,我建议进行一些检查以验证输入,例如缺少字段;如果缺少任何字段,您会看到我死于错误消息。

#!/usr/bin/env perl

use strict;
use lib qw(..);
use JSON qw( );

@ARGV == 2 or die("Infile, Outfile required\n");
open json_fh, "<$ARGV[0]" or die "Couldn't open file $ARGV[0]!\n";
open csv_fh, ">$ARGV[1]" or die "Couldn't open file $ARGV[1]!\n";

my $json_text =<json_fh>;
close json_fh;

my $json = JSON->new->allow_nonref;
my $data = $json->decode($json_text);
my $accounts = $data->{accounts};

my @required = qw(_id accountNumber accountType cardType cardSubType protectionMethod protectionSource expirationDate nameOnAccount cardStatus cardHolderType createdBy addressId productType isDefaultAccount); 
my @opt = (); # learn these
my %col; # key => column index
my $lastIndex;
for (my $i=0; $i<=$#required; ++$i) { $lastIndex = $col{$required[$i]} = $i }
print "There are ", $lastIndex+1, " required cols\n";

foreach my $rec ( @$accounts )
{
    my @row;    
    foreach my $key ( keys %$rec )
    {
        if ( ! exists($col{$key}) ) {
            # new (optional) key
            push @opt, $key;
            $col{$key} = ++$lastIndex;
            print "New col: $key (col ", $lastIndex+1, ")\n";
        }
        $row[$col{$key}] = $rec->{$key};
    }

    # check for all required
    for (my $i=0; $i<=$#required; ++$i) {
        defined($row[$i]) or die("Missing: $required[$i]\n");
    }

    #Write to the file in delimited file format
    print csv_fh join("|", @row), "\n";
}
close csv_fh;