Удалить пустые поля в JSON String в Perl - PullRequest
0 голосов
/ 04 июня 2018

Я модифицирую скрипт Perl, который собирает некоторые данные из различных источников, помещает их в структурированный JSON и вызывает веб-сервис, передавая этот файл JSON.У меня проблема с нулевыми значениями в некоторых из этих полей ...

Это фрагмент моего кода:

  $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 ноль .. как я могуудалить эти нулевые значения?проверять все эти поля?

В настоящее время я использую эти библиотеки

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

Если возможно, я бы не хотел импортировать другие библиотеки или около того.

У меня естьпопробовал проверить, если определен, или поставить if в коде json, но ничего ...

Спасибо за помощь

1 Ответ

0 голосов
/ 04 июня 2018

Умный способ сделать это - использовать модуль JSON для преобразования вашей структуры данных в JSON.Я бы либо постепенно строил новую структуру данных Perl

my $to_json;

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

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

, либо использовал бы встроенные операции с map и grep.

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;

Однако вы говорите, что не можете вносить большие изменения.Вместо этого вам придется разделить код, который выводит 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 или с помощью HEREDOC .

my $json_string = qq({
    "attainable_rate": {
        "down_value": $p->{ATTAINABLE_DN},
        "up_value": $p->{ATTAINABLE_UP}
    }
}
);

my $heredoc = <<JSON
{
    "attainable_rate": {
        "down_value": $p->{ATTAINABLE_DN},
        "up_value": $p->{ATTAINABLE_UP}
    }
}
JSON
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...