1

我正在编写一个脚本,该脚本接收类似于以下对象数组的 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
4

3 回答 3

2

encode_json将生成与使用decode_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 的解析器,您肯定必须自己编写;现有的不这样做。

于 2012-09-28T00:06:56.067 回答
0

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

于 2012-09-28T00:04:29.437 回答
0

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

{ "key": "abc" }

{
  "key" : "abc" 
}

几乎一样。

因此,只需使用您的模块为您提供的重新编码的 JSON。

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

  2. 不关心性能。这些XS模块具有卓越的性能,因为它们是用 C 编码的。如果您对性能有偏执,您不会使用 JSON,而是使用一些二进制格式。而且您不会使用 Perl,而是使用 Fortran ;-)

  3. 您应该将等效数据视为等效数据。即使呈现方式不同。

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

于 2012-09-28T00:04:47.780 回答