删除Perl中JSON字符串中的空字段

时间:2018-06-04 10:09:56

标签: json perl null undef

我正在修改一个Perl脚本,它从各种来源收集一些数据,将它们放入结构化的JSON中并调用传递该JSON文件的Web服务。 我在其中一些字段中遇到空值问题...

这是我的代码片段:

  $p->{BAND_ATTEN_DN1} = 'null';
  $p->{BAND_ATTEN_DN2} = 'null';
  $p->{BAND_ATTEN_DN3} = 'null';
  $p->{BAND_ATTEN_DN4} = 'null';
  $p->{BAND_ATTEN_UP0} = 'null';
  $p->{BAND_ATTEN_UP1} = 'null';
  $p->{BAND_ATTEN_UP2} = 'null';
  $p->{BAND_ATTEN_UP3} = 'null';
  $p->{BAND_ATTEN_UP4} = 'null';
  $p->{BAND_SNR_MARGIN_DN1} = 'null';
  $p->{BAND_SNR_MARGIN_DN2} = 'null';
  $p->{BAND_SNR_MARGIN_DN3} = 'null';
  $p->{BAND_SNR_MARGIN_DN4} = 'null';
  $p->{BAND_SNR_MARGIN_UP0} = 'null';
  $p->{BAND_SNR_MARGIN_UP1} = 'null';
  $p->{BAND_SNR_MARGIN_UP2} = 'null';
  $p->{BAND_SNR_MARGIN_UP3} = 'null';
  $p->{BAND_SNR_MARGIN_UP4} = 'null';
  $p->{BAND_SIG_ATTEN_DN1} = 'null';
  $p->{BAND_SIG_ATTEN_DN2} = 'null';
  $p->{BAND_SIG_ATTEN_DN3} = 'null';
  $p->{BAND_SIG_ATTEN_DN4}  = 'null';

  $p->{BAND_SIG_ATTEN_UP0} = 'null';
  $p->{BAND_SIG_ATTEN_UP1} = 'null';
  $p->{BAND_SIG_ATTEN_UP2} = 'null';
  $p->{BAND_SIG_ATTEN_UP3} = 'null';
  $p->{BAND_SIG_ATTEN_UP4} = 'null';
  $p->{ATTAINABLE_DN} = 'null';
  $p->{ATTAINABLE_UP} = 'null';

  $p->{POWER_DN} = 'null';
  $p->{POWER_UP} = 'null';

  for my $k (keys %$q) {
    $p->{$k} =  ($q->{$k}) ? $q->{$k} : 'null';
  }

  my $m = $measure->{$port};
  for my $k (keys %$m) {
    $p->{$k} =  ($m->{$k}) ? $m->{$k} : 'null';
  }

  my $hlog_up_values = &get_values($delt->{UPHLOG}, 9999, -99);
  my $hlog_dn_values = &get_values($delt->{DOWNHLOG}, 9999, -99);
  my $qln_up_values = &get_values($delt->{UPQLN}, 9999, -199);
  my $qln_dn_values = &get_values($delt->{DOWNQLN}, 9999, -199);
  my $snr_up_values = &get_values($delt->{UPSNR}, 9999, -99);
  my $snr_dn_values = &get_values($delt->{DOWNSNR}, 9999, -99);

  my $hlog_cg_size_dn = grep ($delt->{DOWNHLOGGRUOPSIZE} eq $_,(1,2,4,8,16)) ? $delt->{DOWNHLOGGRUOPSIZE} : $delt->{DOWNHLOGGRUOPSIZE}/4.3125;
  my $hlog_cg_size_up = grep ($delt->{UPHLOGGRUOPSIZE} eq $_,(1,2,4,8,16)) ? $delt->{UPHLOGGRUOPSIZE} : $delt->{UPHLOGGRUOPSIZE}/4.3125;
  my $qln_cg_size_dn = grep ($delt->{DOWNQLNGRUOPSIZE} eq $_,(1,2,4,8,16)) ? $delt->{DOWNQLNGRUOPSIZE} : $delt->{DOWNQLNGRUOPSIZE}/4.3125;
  my $qln_cg_size_up = grep ($delt->{UPQLNGRUOPSIZE} eq $_,(1,2,4,8,16)) ? $delt->{UPQLNGRUOPSIZE} :$delt->{UPQLNGRUOPSIZE}/4.3125;
  my $snr_cg_size_dn = grep ($delt->{DOWNSNRGRUOPSIZE} eq $_,(1,2,4,8,16)) ? $delt->{DOWNSNRGRUOPSIZE} :$delt->{DOWNSNRGRUOPSIZE}/4.3125;
  my $snr_cg_size_up = grep ($delt->{UPSNRGRUOPSIZE} eq $_,(1,2,4,8,16)) ? $delt->{UPSNRGRUOPSIZE} : $delt->{UPSNRGRUOPSIZE}/4.3125;

  my $pots_line_length_A    = defined $plt->{POTS_LINE_LENGTH_A} ? $plt->{POTS_LINE_LENGTH_A} : 'null';
  my $pots_line_length_B    = defined $plt->{POTS_LINE_LENGTH_B} ? $plt->{POTS_LINE_LENGTH_B} : 'null';
  my $pots_line_state       = defined $plt->{POTS_LINE_STATE} ? $plt->{POTS_LINE_STATE} : 'null';
  my $pots_line_termination = defined $plt->{POTS_LINE_TERMINATION_TYPE} ? $plt->{POTS_LINE_TERMINATION_TYPE} : 'null';


  #&_trace("STUB GROUP SIZE",$function, TRC_PDNT);
  #$hlog_cg_size_dn = 8;
  #$hlog_cg_size_up = 8;
  #$qln_cg_size_dn = 8;
  #$qln_cg_size_up = 8;
  #$snr_cg_size_dn = 8;
  #$snr_cg_size_up = 8;


  my $json_string = "{
    \"attainable_rate\": {
      \"down_value\": $p->{ATTAINABLE_DN},
      \"up_value\": $p->{ATTAINABLE_UP}
    },
    \"hlog\": {
      \"up_values\": [$hlog_up_values],
      \"down_values\": [$hlog_dn_values]
    },
    \"hlog_cg_size\": {
      \"down_value\": $hlog_cg_size_dn,
      \"up_value\": $hlog_cg_size_up
    },
    \"qln\": {
      \"down_values\": [$qln_up_values],
      \"up_values\": [$qln_dn_values]
    },
    \"qln_cg_size\": {
      \"down_value\": $qln_cg_size_dn,
      \"up_value\": $qln_cg_size_up
    },
    \"snr\": {
      \"up_values\": [$snr_up_values],
      \"down_values\": [$snr_dn_values]
    },
    \"snr_cg_size\": {
      \"down_value\": $snr_cg_size_dn,
      \"up_value\": $snr_cg_size_up
    },
    \"spectrum\": \"$actual_spectrum\",

    \"rtx_status\": {
      \"down_value\": [
        null
      ],
      \"up_value\": [
        null
      ]
    },
    \"line_attenuation\": {
      \"down_values\": [
        $p->{BAND_ATTEN_DN1},
        $p->{BAND_ATTEN_DN2},
        $p->{BAND_ATTEN_DN3},
        $p->{BAND_ATTEN_DN4}
      ],
      \"up_values\": [
        $p->{BAND_ATTEN_UP0},
        $p->{BAND_ATTEN_UP1},
        $p->{BAND_ATTEN_UP2},
        $p->{BAND_ATTEN_UP3},
        $p->{BAND_ATTEN_UP4}
      ]
    },
    \"noise_margin\": {
      \"down_values\": [
        if($p->{BAND_SNR_MARGIN_DN1},
        $p->{BAND_SNR_MARGIN_DN2},
        $p->{BAND_SNR_MARGIN_DN3},
        $p->{BAND_SNR_MARGIN_DN4}
      ],
      \"up_values\": [
        $p->{BAND_SNR_MARGIN_UP0},
        $p->{BAND_SNR_MARGIN_UP1},
        $p->{BAND_SNR_MARGIN_UP2},
        $p->{BAND_SNR_MARGIN_UP3},
        $p->{BAND_SNR_MARGIN_UP4}
      ]
    },
    \"signal_attenuation\": {
      \"down_values\": [
       $p->{BAND_SIG_ATTEN_DN1},
       $p->{BAND_SIG_ATTEN_DN2},
       $p->{BAND_SIG_ATTEN_DN3},
       $p->{BAND_SIG_ATTEN_DN4}
      ],
      \"up_values\": [
       $p->{BAND_SIG_ATTEN_UP0},
       $p->{BAND_SIG_ATTEN_UP1},
       $p->{BAND_SIG_ATTEN_UP2},
       $p->{BAND_SIG_ATTEN_UP3},
       $p->{BAND_SIG_ATTEN_UP4}
      ]
    },
    \"transmit_power\": {
      \"down_value\": $p->{POWER_DN},
      \"up_value\": $p->{POWER_UP}
    }
  }";

例如(我确定问题仅存在于line_attenuation,signal_attenuation和noise_margin上下)

   \"line_attenuation\": {
      \"down_values\": [
        $p->{BAND_ATTEN_DN1},
        $p->{BAND_ATTEN_DN2},
        $p->{BAND_ATTEN_DN3},
        $p->{BAND_ATTEN_DN4}

如果$p->{BAND_ATTEN_DN4}null我必须只传递前3个值而不是3个有效值+ 1 null ..如何删除这些空值?检查所有这些字段?

目前我正在使用这些库

use strict;
use Data::Dumper;
use Getopt::Long;
use REST::Client;
use DBI;
use JSON;

如果可能,我不想导入其他库。

我已经尝试检查是否已定义,或者将if放在json代码中但没有...

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

执行此操作的明智方法是使用JSON module将您的数据结构转换为JSON。我会逐步构建一个新的Perl数据结构

DEFINE CHL(CLIENT_CHL) CHLTYPE(CLNTCONN) CONNAME('1.2.3.4(9999)') QMNAME(ABC) HBINT(1)

或使用mapgrep的内联操作。

my $to_json;

$to_json->{foo} = $p->{foo};

if ($p->{bar}) {
    $to_json->{baz} = $p->{baz};
}

但是,你说你无法进行大的修改。您必须拆分输出JSON的代码。为了维护起见,这将产生更加丑陋的代码和我强烈建议不要这样做

use strict;
use warnings;
use JSON;

my $p = {
    BAND_ATTEN_DN1 => 1,
    BAND_ATTEN_DN2 => 2,
    BAND_ATTEN_DN3 => 3,
    BAND_ATTEN_DN4 => undef,
};

my $to_json = {
    line_attenuaion => {
        down_values => [
            grep defined, map { $p->{$_} } 
                qw/BAND_ATTEN_DN1 BAND_ATTEN_DN2 BAND_ATTEN_DN3 BAND_ATTEN_DN4/,
        ],
        hashref_slice => [
            grep defined,
                @{$p}{qw/BAND_ATTEN_DN1 BAND_ATTEN_DN2 BAND_ATTEN_DN3 BAND_ATTEN_DN4/},
        ],
    },
    # ...
};

print to_json $to_json;

如果你这样做,那么至少通过将字符串的双引号# HERE BE DRAGONS... my $json_string = "{ \"attainable_rate\": { \"down_value\": $p->{ATTAINABLE_DN}, \"up_value\": $p->{ATTAINABLE_UP} }, \"line_attenuation\": { \"down_values\": [ $p->{BAND_ATTEN_DN1}, $p->{BAND_ATTEN_DN2}, $p->{BAND_ATTEN_DN3}"; if ($p->{BAND_ATTEN_DN4}) { $json_string .= ", $p->{BAND_ATTEN_DN4}"; } $json_string .= " ] } } "; 转换为qq operator或使用HEREDOC来消除所有转义。

""