在 Perl 中删除 JSON 字符串中的空字段
Remove null fields in JSON String in Perl
我正在修改从各种来源收集一些数据的 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 .. 我怎样才能删除那些 null 值?检查所有这些字段?
目前我正在使用这些库
use strict;
use Data::Dumper;
use Getopt::Long;
use REST::Client;
use DBI;
use JSON;
如果可能的话,我不想导入其他库。
我试过检查是否已定义,或将 if 放入 json 代码中,但没有...
感谢帮助
执行此操作的明智方法是使用 JSON module 将您的数据结构转换为 JSON。我要么逐步构建一个新的 Perl 数据结构
my $to_json;
$to_json->{foo} = $p->{foo};
if ($p->{bar}) {
$to_json->{baz} = $p->{baz};
}
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
operator or by using 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
我正在修改从各种来源收集一些数据的 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 .. 我怎样才能删除那些 null 值?检查所有这些字段?
目前我正在使用这些库
use strict;
use Data::Dumper;
use Getopt::Long;
use REST::Client;
use DBI;
use JSON;
如果可能的话,我不想导入其他库。
我试过检查是否已定义,或将 if 放入 json 代码中,但没有...
感谢帮助
执行此操作的明智方法是使用 JSON module 将您的数据结构转换为 JSON。我要么逐步构建一个新的 Perl 数据结构
my $to_json;
$to_json->{foo} = $p->{foo};
if ($p->{bar}) {
$to_json->{baz} = $p->{baz};
}
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
operator or by using 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