1

我的JSON文字如下:

测试.json

{
  "a" : false
}

我想DBM::Deep为上面的 JSON 创建哈希。我的代码如下所示:

数据库文件

use strict;
use warnings;

use DBM::Deep;
use JSON;
use Data::Dumper;

# create the dbm::deep object
my $db = DBM::Deep->new(
    file => 'test.db',
    type => DBM::Deep->TYPE_HASH
);

my $json_text = do {
    open( my $json_fh, $path )
      or die("Can't open \$path\": $!\n");
    local $/;
    <$json_fh>;
};

my $json = JSON->new;
my $data = $json->decode($json_text);
print Dumper($data);

# create dbm::deep hash
eval { $db->{$path} = $data; };

if ($@) {
    print "error : $@\n";
}

执行上述代码时,我得到以下输出/错误:

错误

$VAR1 = { 'a' => bless(do{(my $o = 0)}, 'JSON::XS::Boolean' ) }; 错误:DBM::Deep:不支持“SCALAR”类型的引用存储。在 dbm.pl 第 26 行

看起来,JSON 在内部使用 JSON::XS 来转换 JSON::XS::Boolean 对象中的“真”值,而 DBM::Deep 无法处理这个,而它可以处理空值。

虽然上面的代码适用于以下输入:

{
  "a" : 'true'  # if true is in quotes
}

或者

{
  "a" : null 
}

我尝试了很多东西,但没有任何效果。有没有人有任何解决方法?

4

2 回答 2

1

true您正在使用的 JSON 解析器等返回一个对象,当它遇到或false在 JSON 中时,该对象作为布尔值工作。这允许将数据重新编码为 JSON 而无需更改,但可能会导致此类问题。

null没有这个问题,因为 Perl 有一个undef可以用来明确表示它的本机值 ( )。

下面将这些对象转换为简单的值。

 sub convert_json_bools {
    local *_convert_json_bools = sub {
        my $ref_type = ref($_[0])
            or return;

        if ($ref_type eq 'HASH') {
            _convert_json_bools($_) for values(%{ $_[0] });
        }
        elsif ($ref_type eq 'ARRAY') {
            _convert_json_bools($_) for @{ $_[0] };
        }
        elsif ($ref_type =~ /::Boolean\z/) {
            $_[0] = $_[0] ? 1 : 0;
        }
        else {
            warn("Unsupported type $ref_type\n");
        }
    };

    &_convert_json_bools;
}

convert_json_bools($data);
于 2016-06-22T16:39:24.860 回答
-2

你的代码对我来说很好,唯一的改变是设置

my $path = 'test.json';

您应该检查您的模块版本号。这些是我拥有的

print $DBM::Deep::VERSION, "\n";    # 2.0013
print $JSON::VERSION, "\n";         # 2.90
print $JSON::XS::VERSION, "\n";     # 3.02

我正在运行 Perl v5.24.0

转储的输出如下

新建的DBM::Deep数据库

$VAR1 = bless( {}, 'DBM::Deep::Hash' );

的输出$json->decode

$VAR1 = {
          'a' => undef
        };

之后填充DBM::Deep的数据库eval

$VAR1 = bless( {
                 'test.json' => bless( {
                                         'a' => undef
                                       }, 'DBM::Deep::Hash' )
               }, 'DBM::Deep::Hash' );

所有这一切看起来都应该如此

于 2016-06-22T16:50:51.857 回答