从Perl中的解码数组节点检索原始JSON代码

时间:2012-09-27 23:54:45

标签: json perl utf-8

我正在编写一个脚本,该脚本接收类似于此的对象数组的JSON代码:

{
  "array":[
    { "id": 1, "text": "Some text" },
    { "id": 2, "text": "Some text" }
  ]
}

我使用JSON :: XS对其进行解码,然后过滤掉一些结果。在此之后,我需要将每个单独节点的JSON代码存储到队列中以供稍后处理。此队列所需的格式也是JSON,因此我需要为每个节点插入的代码如下所示:

{ "id": 1, "text": "Some text" }

然而,在 decode_json 解码了一个节点之后,剩下的就是每个节点的哈希引用:

print $json->{'array'}[0]; # Would print something like HASH(0x7ffa80c83270)

我知道我可以在哈希引用上使用 encode_json 获得类似于原始JSON代码的东西,但结果代码与原始代码不同,UTF-8字符变得奇怪,而且它看起来像是一些额外的处理,特别是考虑到这个脚本必须处理的数据量。

有没有办法从解码的数组节点中检索原始JSON代码? JSON :: XS在解码后是否将原始块保留在某处?


修改

关于奇怪的UTF-8字符,它们在屏幕上看起来很奇怪:

#!/usr/bin/perl

use utf8;
use JSON::XS;
binmode STDOUT, ":utf8";

$old_json = '{ "text": "Drag\u00f3n" }';
$json = decode_json($old_json);
print $json->{'text'}; # Dragón

$new_json = encode_json($json);
print $new_json; # {"text":"Dragón"}

$json = decode_json($new_json);
print $json->{'text'}; # Dragón

3 个答案:

答案 0 :(得分:2)

在使用encode_json对其进行解码之前,

decode_json将生成等效的JSON。使用UTF-8编码的字符并不奇怪。

$ cat a.pl
use Encode   qw( encode_utf8 );
use JSON::XS qw( decode_json encode_json );

my $json = encode_utf8(qq!{"name":"\x{C9}ric" }!);
print($json, "\n");
print(encode_json(decode_json($json)), "\n");

$ perl a.pl | od -c
0000000   {   "   n   a   m   e   "   :   " 303 211   r   i   c   "    
0000020   }  \n   {   "   n   a   m   e   "   :   " 303 211   r   i   c
0000040   "   }  \n
0000043

如果你想要一个保留原始JSON的解析器,你肯定要写自己的;现有的不这样做。

答案 1 :(得分:0)

不,它在任何地方都不存在。 “原始JSON”不是按元素存储的;它只需一次通过解码。

答案 2 :(得分:0)

不,这是不可能的。每个JSON对象都可以有多个但等效的表示形式:

{ "key": "abc" }

{
  "key" : "abc" 
}

几乎是一样的。

所以只需使用模块为您提供的重新编码的JSON。

  1. 即使JSON :: XS缓存了这些块,提取它们也会破坏封装,因此如果模块升级则无法保证工作。这是糟糕的设计。

  2. 不关心表现。 XS模块具有出色的性能,因为它们用C编码。如果你对性能很偏执,你就不会使用JSON而是一些二进制格式。你不会使用Perl,而是使用Fortran; - )

  3. 您应该将等效数据视为等效数据。即使演示文稿不同。

  4. 如果unicode字符看起来很奇怪,但处理正常,则没有问题。如果未正确处理它们,则可能必须指定精确编码。