我有一个json结构加载到散列中,如下所示:
my $data = {
"store1" => {
"book" => [
{ "category" => "reference",
"author" => "Nigel Rees",
"title" => "Sayings of the Century",
"price" => 8.95,
},
{ "category" => "fiction",
"author" => "Herman Melville",
"title" => "Moby Dick",
"isbn" => "0-553-21311-3",
"price" => 8.99,
},
],
"bicycle" => [
{ "color" => "red",
"price" => 19.95,
},
],
},
"store2" => {
"book" => [
{ "category" => "reference",
"author" => "Nigel Rees",
"title" => "Sayings of the Century",
"price" => 8.95,
},
{ "category" => "fiction",
"author" => "Herman Melville",
"title" => "Moby Dick",
"isbn" => "0-553-21311-3",
"price" => 8.99,
},
],
"bicycle" => [
{ "color" => "red",
"price" => 19.95,
},
],
},
};
像JSON::Path这样的工具,返回与路径匹配的元素值。
my $jpath = JSON::Path->new('$.*.book[*]');
my @books = $jpath->values($data);
我想要得到路径,而不是值。比如:
[
'$->{store}{book}[0]',
'$->{store}{book}[1]',
'$->{store}{book}[2]'
]
我想在路径中查找信息,以便知道结果的位置而不是结果本身。例如,给定查询:
my $jpath = JSON::Path->new('$.*.book[*]');
我想知道路径是否包含"store1"或"store2",所以我需要查询返回路径。
有办法做到这一点吗?
谢谢,斯皮罗
您应该能够使用paths
。
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
my $data = {
"store" => {
"book" => [
{ "category" => "reference",
"author" => "Nigel Rees",
"title" => "Sayings of the Century",
"price" => 8.95,
},
{ "category" => "fiction",
"author" => "Evelyn Waugh",
"title" => "Sword of Honour",
"price" => 12.99,
},
{ "category" => "fiction",
"author" => "Herman Melville",
"title" => "Moby Dick",
"isbn" => "0-553-21311-3",
"price" => 8.99,
},
{ "category" => "fiction",
"author" => "J. R. R. Tolkien",
"title" => "The Lord of the Rings",
"isbn" => "0-395-19395-8",
"price" => 22.99,
},
],
"bicycle" => [
{ "color" => "red",
"price" => 19.95,
},
],
},
};
# All books in the store
my $jpath = JSON::Path->new('$.store.book[*]');
my @books = $jpath->paths($data);
say for @books;
输出:
$['store']['book']['0']
$['store']['book']['1']
$['store']['book']['2']
$['store']['book']['3']
现在,在这种情况下,您似乎想要有一个存储列表,而不使用适合存储列表的数据结构。也就是说,更合适的是:
my $data = {
stores => [
# each store is product type to list of
# products of that type in that store
]
};
每个store可能也应该有一个name属性。
我假设在现实生活中您没有模拟名称中带有整数后缀的数组。在这种情况下,顶级键可以是任意字符串。因此,使用您提供的$data
结构,
# All books in all stores
my $jpath = JSON::Path->new('$.*.book[*]');
my @books = $jpath->paths($data);
say for @books;
输出:
$['store1']['book']['0']
$['store1']['book']['1']
$['store2']['book']['0']
$['store2']['book']['1']