【问题标题】:from_json and decode_json in perl not working as expectedperl 中的 from_json 和 decode_json 无法按预期工作
【发布时间】:2016-03-23 03:35:10
【问题描述】:

我有一个像下面这样的 json。

$response = {"entries":[{"content":{"eStatus":0,"id":"0","enabled":false,"isOK":false,}}]}
 $responseContent = from_json($response);

当我在我的 perl 代码中使用 from_json 或 decode_json 时,我得到以下转换后的 json。

                     'content' => {
                                      'id' => '0',
                                      'esrsVeAddress' => '',
                                      'isOK' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
                                      'enabled' => $VAR1->{'entries'}[0]{'content'}{'isOK'},
                                      'eStatus' => 0
                                    }

当元素的值不是布尔值(真/假)时,转换正确发生,但当其布尔值时,输出被破坏。

如果您将看到元素 'enabled' 和 'isOK' 的值都是错误的。

我在这里使用了错误的函数“from_json”还是“decode_json”。

感谢任何建议或指导。

这是我尝试使用元素值 isOK 并启用的方式。

  if (  $isOK = $responseContent->{'entries'}[0]->{'content'}->     {'isOK'} eq "1" ) {
     c4lx_log "value is found to be true and so do some business logic";
 }
 else {
    c4lx_log "value is found to be false and so dont do anything here";
 }

注意: 函数“from_json”或“decode_json”的输入来自 REST 响应,格式如上所示。我已验证输入是否正确传递并符合预期。它只是这里的转换问题。

【问题讨论】:

  • JSON::PP::Boolean 只是一个包含 0(Perl 中为假)和 1(Perl 中为真)的对象。没有任何损坏。
  • 为什么我看到这样的价值 'isOK' => bless(do{(my $o = 0)}, 'JSON::PP::Boolean' ), 'enabled' => $ VAR1->{'entries'}[0]{'content'}{'isOK'},
  • 正确的转换应该如下 'isOK' => false, 'enabled' => false,
  • 因为字符串 false 在 Perl 中是真实的。 JSON.pm 为布尔值创建了一个包装器,因此它们在 Perl 中的含义与在原始 JSON 中的含义相同。见metacpan.org/pod/JSON#true-false
  • 正确我同意。但我的问题是为什么我将值视为 'bless(do{(my $o = 0)}, 'JSON::PP::Boolean')' 而不是 false 或 1/0。我怎样才能避免像上面这样的转换。

标签: json perl


【解决方案1】:

如果你会看到元素 'enabled' 和 'isOK' 的值都是错误的。

不,他们是正确的。 ->{enabled}->{isOK} 在 JSON 中都是 false。

我怎样才能避免像上面这样的转换

您实际上是在问为什么模块 将值转换(到字符串或数字)。这会导致信息丢失。例如,如果您希望执行转换,encode_json(decode_json($json)) 会更改数据。

在这里可以做些什么来实现我所期望的价值 [即]'content' => { 'id' => '0', 'esrsVeAddress' => '', 'isOK' => false, 'enabled' => false, 'eStatus' => 0 }

使用 Data::Dumper 是不可能的。 Data::Dumper 产生有效的 Perl 代码,而那不是有效的 Perl 代码。但是,您可以通过使用来接近它

print(Data::Dumper->Dump(
   [ JSON::false, JSON::true, $responseContent ],
   [qw( $false $true $responseContent )]));

它产生以下输出:

$false = bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' );
$true = bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' );
$responseContent = {
                     'entries' => [
                                    {
                                      'content' => {
                                                     'id' => '0',
                                                     'eStatus' => 0,
                                                     'enabled' => $false,
                                                     'isOK' => $false
                                                   }
                                    }
                                  ]
                   };

这是我尝试使用元素 isOKenabled 的值的方式。

期望布尔值具有特定值是错误的。改变

my $isOK;  
if ($isOK = $responseContent->{'entries'}[0]->{'content'}->{'isOK'} eq "1")

if ($responseContent->{'entries'}[0]->{'content'}->{'isOK'})

这可以简化为

if ($responseContent->{entries}[0]{content}{isOK})

如果您想存储结果以供以后使用,请使用

my $isOK = $responseContent->{entries}[0]{content}{isOK};
if ($isOK)

【讨论】:

  • 正确。我的问题是如何避免这里的转换。我的代码尝试使用特定元素“isOK”和“启用”的值来执行一些逻辑。但在当前情况下,价值并没有达到预期
  • 如果你会看到 enabled 的值如下:'enabled' => $VAR1->{'entries'}[0]{'content'}{'isOK'}。它指的是OK,这对我来说看起来很奇怪
  • 我想要的只是假,要么保持假,要么得到 1/0。一些可靠的值,我总是可以依靠它来使逻辑工作
  • 这里可以做些什么来使我期望的值要么是假的,要么是我可以随时回复的任何值
  • 示例转换的 json 可以如下所示: 'content' => { 'id' => '0', 'esrsVeAddress' => '', 'isOK' => false, 'enabled' = > false, 'eStatus' => 0 } 而不是上面显示的一个。
猜你喜欢
  • 2012-03-05
  • 2014-09-22
  • 2014-08-03
  • 1970-01-01
  • 2013-12-23
  • 2014-12-09
  • 2016-01-13
  • 2020-09-21
  • 2011-08-17
相关资源
最近更新 更多