JsonPath - 提取满足多个条件的对象?
JsonPath - Extract object meeting multiple criteria?
在下面给出的 Json 字符串中,我想找到 category = m 且 "middle" 数组包含符合此条件的元素的所有元素 - 元素的 "middle" 数组具有 itemType = Executable 的对象。
我想使用 jsonpath 来获取所需的对象。我宁愿不使用 jmespath,因为它对于我的目的来说可能太复杂了。但是,我是 jsonpath 的新手,我无法从过于琐碎或基础的在线教程中找出 json 查询。我想知道使用编程语言来获取我需要的数据是否更好。请指教
到目前为止,通过使用此 json 路径查询 $.[?(@.category=="m")]
,我只能提取类别 = m 的元素。剩下的部分怎么办?
Json :
概述 - 每个对象都有一个 "content" 对象。每个内容对象除了其他字段外,通常还有一个开始、中间和结束数组。中间数组可以在其中包含多个内容对象,依此类推。一些内容对象只有一个中间数组。我对在上述内容对象中定位项目很感兴趣。
请注意,这不是我必须处理的实际 json。这是经过 SO 消毒的仿制品。
{
"id": "123",
"contents": {
"title": "B1",
"start": [],
"middle": [
{
"level": "1",
"contents": {
"title": "C1",
"category": "c",
"start": [],
"middle": [
{
"level": "2",
"contents": {
"title": "M1",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec1"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT3",
"middle": [
{
"itemType": "Data"
}
]
}
}
],
"end": []
}
},
{
"level": "2",
"contents": {
"title": "M2",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec2"
}
]
}
}
],
"end": []
}
}
],
"end": []
}
},
{
"level": "1",
"contents": {
"title": "C2",
"category": "c",
"start": [],
"middle": [
{
"level": "2",
"contents": {
"title": "M1",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec3"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT3",
"middle": [
{
"itemType": "Data"
}
]
}
}
],
"end": []
}
},
{
"level": "2",
"contents": {
"title": "M2",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec4"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT3",
"middle": [
{
"itemType": "Data"
}
]
}
}
],
"end": []
}
}
],
"end": []
}
}
],
"end": []
}
}
上下文
- json 嵌套对象1
- json路径表达式语言
- 在 jsonpath 和 jmespath(或其他 JSON 表达式引擎)之间进行选择
问题
- DeveMasterJoe2 想从嵌套的 JSON
中提取一些值
讨论
- 有很多 jsonpath 的实现,它们并不都支持相同的功能
- 源JSON的结构和规范化将影响使用纯json路径
完成此操作的难易程度
- 在选择JSON表达式引擎时,必须权衡多个因素
- 跨语言的实现有多一致?
- 给定语言中有多少种选择?
- 规范的清晰度如何?
- 有多少示例、单元测试或教程可用?
- 谁支持?
使用 Python 和 jsonpath-ng
的示例解决方案
- 这是一个使用 python 3.7 和 jsonpath-ng
的示例解决方案
- 这个例子混合使用了 jsonpath 和 python 而不是纯粹的 jsonpath,因为 JSON
- 我会留给其他人提供依赖于纯 jsonpath
的答案
- 请注意,来源 JSON 可以说是可以稍微清理一下
- (例如,为什么
itemType==Data
个元素没有附加 id 字段?)
- (例如,为什么在所有
contents
元素上都找不到 category
?)
- (例如,如果您明确指定
level
,当您可以通过 level
确定深度时,为什么要使具有大量嵌套对象的事情复杂化?)
This example:
## import libraries
import codecs
import json
import jsonpath_ng
from jsonpath_ng.ext import parse
##;;
## init vars
href="path/to/my/jsonfile/nested_dict.json"
json_string = codecs.open(href, 'rb', encoding='utf8').read()
json_dataroot = json.loads(json_string)
final_result = []
##;;
## init jsonpath outer-query
match = parse('$..contents.middle[*]').find(json_dataroot)
##;;
## iterate through outer-query and gather subelements
for ijj,item in enumerate(match):
## restrict to desired category == 'm'
if(match[ijj].value.get('contents',{}).get('category','') == 'm'):
## extract out desired subelements
json_datafrag001 = [item.get('contents',{}).get('middle',{})[0]
for item in match[ijj].value.get('contents',{}).get('middle',{})
]
match001 = parse("$[?(@.itemType=='Executable')]").find(json_datafrag001)
final_result.extend(list(match001[ikk].value for ikk,item in enumerate(match001)))
pass
##;;
## show final result
vout = json.dumps(final_result, sort_keys=True,indent=4, separators=(',', ': '))
print(vout)
##;;
... produces this result ...
[
{
"id": "exec1",
"itemType": "Executable"
},
{
"id": "exec2",
"itemType": "Executable"
},
{
"id": "exec3",
"itemType": "Executable"
},
{
"id": "exec4",
"itemType": "Executable"
}
]
1(又名字典、关联数组、散列)
在下面给出的 Json 字符串中,我想找到 category = m 且 "middle" 数组包含符合此条件的元素的所有元素 - 元素的 "middle" 数组具有 itemType = Executable 的对象。
我想使用 jsonpath 来获取所需的对象。我宁愿不使用 jmespath,因为它对于我的目的来说可能太复杂了。但是,我是 jsonpath 的新手,我无法从过于琐碎或基础的在线教程中找出 json 查询。我想知道使用编程语言来获取我需要的数据是否更好。请指教
到目前为止,通过使用此 json 路径查询 $.[?(@.category=="m")]
,我只能提取类别 = m 的元素。剩下的部分怎么办?
Json : 概述 - 每个对象都有一个 "content" 对象。每个内容对象除了其他字段外,通常还有一个开始、中间和结束数组。中间数组可以在其中包含多个内容对象,依此类推。一些内容对象只有一个中间数组。我对在上述内容对象中定位项目很感兴趣。
请注意,这不是我必须处理的实际 json。这是经过 SO 消毒的仿制品。
{
"id": "123",
"contents": {
"title": "B1",
"start": [],
"middle": [
{
"level": "1",
"contents": {
"title": "C1",
"category": "c",
"start": [],
"middle": [
{
"level": "2",
"contents": {
"title": "M1",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec1"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT3",
"middle": [
{
"itemType": "Data"
}
]
}
}
],
"end": []
}
},
{
"level": "2",
"contents": {
"title": "M2",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec2"
}
]
}
}
],
"end": []
}
}
],
"end": []
}
},
{
"level": "1",
"contents": {
"title": "C2",
"category": "c",
"start": [],
"middle": [
{
"level": "2",
"contents": {
"title": "M1",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec3"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT3",
"middle": [
{
"itemType": "Data"
}
]
}
}
],
"end": []
}
},
{
"level": "2",
"contents": {
"title": "M2",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec4"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT3",
"middle": [
{
"itemType": "Data"
}
]
}
}
],
"end": []
}
}
],
"end": []
}
}
],
"end": []
}
}
上下文
- json 嵌套对象1
- json路径表达式语言
- 在 jsonpath 和 jmespath(或其他 JSON 表达式引擎)之间进行选择
问题
- DeveMasterJoe2 想从嵌套的 JSON 中提取一些值
讨论
- 有很多 jsonpath 的实现,它们并不都支持相同的功能
- 源JSON的结构和规范化将影响使用纯json路径 完成此操作的难易程度
- 在选择JSON表达式引擎时,必须权衡多个因素
- 跨语言的实现有多一致?
- 给定语言中有多少种选择?
- 规范的清晰度如何?
- 有多少示例、单元测试或教程可用?
- 谁支持?
使用 Python 和 jsonpath-ng
的示例解决方案- 这是一个使用 python 3.7 和 jsonpath-ng 的示例解决方案
- 这个例子混合使用了 jsonpath 和 python 而不是纯粹的 jsonpath,因为 JSON
- 我会留给其他人提供依赖于纯 jsonpath 的答案
- 请注意,来源 JSON 可以说是可以稍微清理一下
- (例如,为什么
itemType==Data
个元素没有附加 id 字段?) - (例如,为什么在所有
contents
元素上都找不到category
?) - (例如,如果您明确指定
level
,当您可以通过level
确定深度时,为什么要使具有大量嵌套对象的事情复杂化?)
- (例如,为什么
This example:
## import libraries
import codecs
import json
import jsonpath_ng
from jsonpath_ng.ext import parse
##;;
## init vars
href="path/to/my/jsonfile/nested_dict.json"
json_string = codecs.open(href, 'rb', encoding='utf8').read()
json_dataroot = json.loads(json_string)
final_result = []
##;;
## init jsonpath outer-query
match = parse('$..contents.middle[*]').find(json_dataroot)
##;;
## iterate through outer-query and gather subelements
for ijj,item in enumerate(match):
## restrict to desired category == 'm'
if(match[ijj].value.get('contents',{}).get('category','') == 'm'):
## extract out desired subelements
json_datafrag001 = [item.get('contents',{}).get('middle',{})[0]
for item in match[ijj].value.get('contents',{}).get('middle',{})
]
match001 = parse("$[?(@.itemType=='Executable')]").find(json_datafrag001)
final_result.extend(list(match001[ikk].value for ikk,item in enumerate(match001)))
pass
##;;
## show final result
vout = json.dumps(final_result, sort_keys=True,indent=4, separators=(',', ': '))
print(vout)
##;;
... produces this result ...
[
{
"id": "exec1",
"itemType": "Executable"
},
{
"id": "exec2",
"itemType": "Executable"
},
{
"id": "exec3",
"itemType": "Executable"
},
{
"id": "exec4",
"itemType": "Executable"
}
]
1(又名字典、关联数组、散列)