Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Perl中从解码的数组节点检索原始JSON代码_Json_Perl_Utf 8 - Fatal编程技术网

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

在Perl中从解码的数组节点检索原始JSON代码,json,perl,utf-8,Json,Perl,Utf 8,我正在编写一个脚本,该脚本接收类似以下内容的对象数组的JSON代码: { "array":[ { "id": 1, "text": "Some text" }, { "id": 2, "text": "Some text" } ] } 我使用JSON::XS对其进行解码,然后过滤掉一些结果。在此之后,我需要将每个节点的JSON代码存储到队列中,以供以后处理。此队列所需的格式也是JSON,因此我需要为每个节点插入如下代码: { "id": 1, "text": "Some

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

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

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

{ "key": "abc" }

都差不多

因此,只需使用模块提供的重新编码的JSON即可

  • 即使JSON::XS缓存块,提取它们也会违反封装,因此无法保证在模块升级时工作。这是一个糟糕的设计

  • 不要在意表现。
    XS
    模块具有优异的性能,因为它们是用C编写的。如果您对性能有疑虑,您不会使用JSON,而是使用一些二进制格式。您不会使用Perl,而是Fortran;-)

  • 应将等效数据视为等效数据。即使演示不同

  • 如果unicode字符看起来很奇怪,但处理过程很好,那么就没有问题了。如果它们没有得到正确的处理,您可能必须指定精确的编码


  • encode_json
    将生成与您使用
    decode_json
    解码之前的原始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的解析器,那么您肯定需要编写自己的解析器;现有的字符不会这样做。

    如果你说的“怪异”是指它将6个字符的UTF-8编码(5C 75 32 36 30)
    \u2660
    替换为表示该字符的UTF-8编码(E2 99 A0)(♠), 你错了。这很好。所以…现在JSON代码进入MySQL队列,我提取它,当我尝试解码它时,我得到了这个错误:JSON字符串中格式错误的UTF-8字符…有什么想法吗?是的,注释不是提出新问题的地方。请确保数据准确无误(
    use Data::Dumper;local$Data::Dumper::Useqq=1;print(Dumper(…);
    )对此很抱歉…只是想了解一下规则。我在解码JSON之前先将其编码到UTF-8解决了这个问题非常确定您遇到了“两错一对”的情况。您正在解码,而不仅仅是解码。重新编码以前解码的内容感觉像是性能问题……但是,除非我自己编写解析器,否则我似乎不得不放弃。非常感谢。重新编辑:是的,当您使用UTF-8两次,在UTF-8终端上看起来会很奇怪。不要这样做。记住
    decode\u json
    encode\u json
    的缩写。
    $ 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