use strict;
use warnings;
use JSON::Streaming::Reader;
use JSON 'to_json';
my $s = '{"Name":[[1,1],[1,2],[2,1]],"Name2":[[3,2]]}';
my $jsonr = JSON::Streaming::Reader->for_string($s);
my @data;
while (my $token = $jsonr->get_token) {
my ($key, $value) = @$token;
if ($key eq 'start_property') {
push @data, { $value => $jsonr->slurp };
}
}
print to_json(\@data);
use Monkey::Patch qw[patch_package];
# Monkey-patch JSON::PP::object() subroutine to use Tie::IxHash.
my $handle = patch_package 'JSON::PP' => 'object' => sub {
my $orig = shift;
my %obj;
tie %obj, 'Tie::IxHash' or die "tie(\%obj, 'Tie::IxHash') failed!\n";
$orig->(\%obj)
};
5条答案
按热度按时间deyfvvtc1#
你需要使用一个流JSON解码器,比如
JSON::Streaming::Reader
。然后你可以将你的JSON存储为一个键/值对数组,而不是哈希。如何使用它的实际实现在很大程度上取决于数据的结构,但是给出了一个简单的例子......这里有一个简单的实现。
此脚本的输出始终为:
z5btuh9x2#
好吧,我设法解决了我的问题,但它不是一个通用的解决方案,所以它可能不会帮助休闲读者.无论如何,我得到了使用数据库的帮助键的顺序,我这样调用我的函数:
然后我按照第二个参数的顺序遍历了这些键,并将结果放入一个新的绑定(IxHash)哈希中,然后用json对其进行编码。
很遗憾的是,没有perl json解码器可以保留键的顺序,而我所使用的其他东西,至少在这个项目中,都是这样(php,postgres,firefox,Chrome)。
rdlzhqv93#
@soger,谢谢你5年前在上面评论的想法!
我查看了JSON::PP代码,我只需要在名为object()的函数的开头添加一个绑定到IxHash。
绝妙的解决方案!谢谢你的想法。我想出了如何实现这一点,使用
Monkey::Patch
模块 PackageJSON::PP::object()
函数,使其使用Tie::IxHash
,而不接触安装的JSON::PP
文件:运行上述代码后,只要
$handle
仍在作用域中,JSON::PP::decode_json
将对所有JSON对象使用Tie::IxHash。我测试了阅读JSON文件,使用JSON::PP::decode_json
解码,然后使用JSON::PP::encode_json
将生成的数据结构编码回JSON,并将其写入新的JSON文件。然后我通过jq .
运行原始JSON文件和新JSON文件,以规范化格式并比较结果。它们是100%逐字节相同的。👍(Of当然,理想情况下,
JSON::PP
应该将其作为开箱即用的内置选项提供!)wqsoz72f4#
JSON对象是无序的。您必须以某种方式将所需的顺序编码到数据中
mbyulnm05#
可能你想要像SAX解析器一样的JSON数据流解码器。如果是这样,请参阅
JSON::Streaming::Reader
或JSON::SL
。