正确且简单的方法将JSON :: PP :: Boolean转换为Perl的0,1



尝试将JSON转换为YAML。有此代码

#!/usr/bin/env perl
use 5.014;
use warnings;
use JSON;
use YAML;
my $json_string = q(
{
   "some" : [
      { "isFlagged" : true, "name" : "Some name" },
      { "isFlagged" : false, "name" : "Some other name" }
   ]
}
);
my $data = decode_json($json_string);
say Dump($data);

它产生:

---
some:
  - isFlagged: !!perl/scalar:JSON::PP::Boolean 1
    name: Some name
  - isFlagged: !!perl/scalar:JSON::PP::Boolean 0
    name: Some other name

我需要将JSON::PP::Boolean对象转换为01。当然,我可以从YAML输出中删除每个!!perl/scalar:JSON::PP::Boolean字符串,但这在我看来并不是一个正确的解决方案。

那么,什么是简单正确的方法将所有JSON::PP::Boolean对象转换为简单的01,因此YAML将生成

---
some:
  - isFlagged: 1
    name: Some name
  - isFlagged: 0
    name: Some other name

使用YAML的Stringify选项:

{
    local $YAML::Stringify = 1;
    say Dump($data);
}

这使yaml使用JSON :: PP ::布尔值的弦乐超载,而不是倾倒对象内部。

一般解决方案:

use Carp qw( carp );
sub convert_bools {
    my %unrecognized;
    local *_convert_bools = sub {
        my $ref_type = ref($_[0]);
        if (!$ref_type) {
            # Nothing.
        }
        elsif ($ref_type eq 'HASH') {
            _convert_bools($_) for values(%{ $_[0] });
        }
        elsif ($ref_type eq 'ARRAY') {
            _convert_bools($_) for @{ $_[0] };
        }
        elsif (
               $ref_type eq 'JSON::PP::Boolean'           # JSON::PP
            || $ref_type eq 'Types::Serialiser::Boolean'  # JSON::XS
        ) {
            $_[0] = $_[0] ? 1 : 0;
        }
        else {
            ++$unrecognized{$ref_type};
        }
    };
    &_convert_bools;
    carp("Encountered an object of unrecognized type $_")
        for sort values(%unrecognized);
}
my $data = decode_json($json);
convert_bools($data);

使用yaml :: xs 0.67或更高,您可以执行以下操作:

#!/usr/bin/env perl
use 5.014;
use warnings;
use JSON;
use YAML::XS;
my $json_string = q(
{
   "some" : [
      { "isFlagged" : true, "name" : "Some name" },
      { "isFlagged" : false, "name" : "Some other name" }
   ]
}
);
my $data = decode_json($json_string);
local $YAML::XS::Boolean = 'JSON::PP';
say Dump($data);

最新更新