Python_json数据检索与定位之jsonPath类库
json数据检索与定位之jsonPath类库
by:授客 QQ:1033553122
实践环境
win7 64
Python 3.4.0
jsonpath_ng-1.4.3-py2.py3-none-any.whl
下载地址:
https://pypi.org/project/jsonpath-ng/#files
https://pan.baidu.com/s/1AdbGqz1brNYBOqmIbWaAYg
使用详解
官方实例
>>> from jsonpath_ng import jsonpath, parse
>>> jsonpath_expr = parse('foo[*].baz')
# 提取值
>>> [match.value for match in jsonpath_expr.find({'foo':[{'baz':1}, {'baz':2}]})]
[1, 2]
# 获取匹配值对应的路径
>>> [str(match.full_path) for match in jsonpath_expr.find({'foo': [{'baz': 1}, {'baz': 2}]})]
['foo.[0].baz', 'foo.[1].baz']
# 自动提供id
>>> [match.value for match in parse('foo[*].id').find({'foo': [{'id': 'bizzle'}, {'baz': 3}]})]
['bizzle']
>>> jsonpath.auto_id_field = 'id'
>>> [match.value for match in parse('foo[*].id').find({'foo': [{'id': 'bizzle'}, {'baz': 3}]})]
['foo.bizzle', 'foo.[1]']
# 扩展功能之一 命名操作符 `parent`
>>> [match.value for match in parse('a.*.b.`parent`.c').find({'a': {'x': {'b': 1, 'c': 'number one'}, 'y': {'b': 2, 'c': 'number two'}}})]
['number one', 'number two']
>>> ['number two', 'number one']
使用扩展的解析器
好处是有更强大的扩展功能
>>> from jsonpath_ng.ext import parse
>>> jsonpath_expr = parse('foo[*].baz')
jsonpath 语法
基础语法(Atomic expressions)
$ 根对象
`this` 当前对象
`foo` More generally, this syntax allows "named operators" to extend JSONPath is arbitrary ways
field 指定具体的字段
[ field ] 同field
[ idx ] 数组访问 Array access, described below (this is always unambiguous with field access)
例子
获取根对象
>>> parse('$').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}]})
[DatumInContext(value={'key2': {'id': 2}, 'key3': [{'id': 3}, {'name': 'shouke'}], 'key1': {'id': 1}}, path=Root(), context=None)]
>>> [match.value for match in parse('$').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}]})]
[{'key2': {'id': 2}, 'key3': [{'id': 3}, {'name': 'shouke'}], 'key1': {'id': 1}}]
获取一级键对应的值
>>> [match.value for match in parse('key1').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}]})]
[{'id': 1}]
>>> [match.value for match in parse('[key1]').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}]})]
[{'id': 1}]
# 注意:单独使用 filed、 [filed] 语法,field仅支持字典的一级键
[{'key2': {'id': 2}, 'key3': [{'id': 3}, {'name': 'shouke'}], 'key1': {'id': 1}}]
>>> [match.value for match in parse('id').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}]})]
[]
# 注意:单独使用 filed、 [filed] 语法,根对象必须是字典,不能是数组
>>> [match.value for match in parse('[key1]').find([{'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}]}])]
[]
数组访问
>>> [match.value for match in parse('[0]').find([{'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}]}])]
[{'key2': {'id': 2}, 'key3': [{'id': 3}, {'name': 'shouke'}], 'key1': {'id': 1}}]
jsonpath操作符
jsonpath1 . jsonpath2 匹配jsonpath2,并且父节点匹配jsonpath1的所有节点(All nodes matched by jsonpath2 starting at any node matching jsonpath1) 注意:仅针对字典可用
注:有无空格不影响,比如jsonpath1.jsonpath2 下同
jsonpath [ whatever ] 如果是字典,同jsonpath.whatever,如果是数组,则表示按索引访问数组
jsonpath1 .. jsonpath2 匹配jsonpath2,并且由匹配jsonpath1的父节点派生的所有节点
jsonpath1 where jsonpath2 匹配jsonpath1并且携带一个匹配jsonpath2直接子节点(非派生子节点)的所有节点(Any nodes matching jsonpath1 with a child matching jsonpath2)
jsonpath1 | jsonpath2 匹配jsonpath1,或者jsonpath2的所有节点的集合(注:有时候结果似乎和描述不符,具体见例子
例子
jsonpath1 . jsonpath2
>>> [match.value for match in parse('key1.id').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}]})]
[1]
jsonpath [ whatever ]
>>> [match.value for match in parse('key1[id]').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}]})]
[1]
>>> [match.value for match in parse('key3[0]').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}]})]
[{'id': 3}]
jsonpath1 .. jsonpath2
>>> [match.value for match in parse('key3..id').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':{'key4':{'key5':{'id':3, 'name':'shouke'}}}})]
[3]
>>> [match.value for match in parse('key3..id').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}, {'id':4, 'name':'keshou'}]})]
[3, 4]
jsonpath1 where jsonpath2
>>> [match.value for match in parse('key2 where id').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}, {'id':4, 'name':'keshou'
[{'id': 2}]
注意:匹配jsonpath2的必须是直接子节点
>>> [match.value for match in parse('key3 where id').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}, {'id':4, 'name':'keshou'
[]
>>> [match.value for match in parse('key3 where id').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':{'key4':{'key5':{'id':3, 'name':'shouke'}}}})]
[]
jsonpath1 | jsonpath2
>>> [match.value for match in parse('key1 | key3 ').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':{'key4':{'key5':{'id':3, 'name':'shouke'}}}})]
[{'id': 1}, {'key4': {'key5': {'name': 'shouke', 'id': 3}}}]
>>> [match.value for match in parse('key1 | key3.key4 ').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':{'key4':{'key5':{'id':3, 'name':'shouke'}}}})]
[{'key5': {'name': 'shouke', 'id': 3}}]
字段说明(field)
fieldname 来自当前对象的字段名称
"fieldname" 同上,允许fieldname中包含指定字符
'fieldname' 同上
* 任意字段名称
field , field 指定多个字段
例子
*
>>> [match.value for match in parse('key1.*').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':{'key4':{'key5':{'id':3, 'name':'shouke'}}}})]
[1]
注意:如果是jsonpath1.* 返回的是最后层级的值
>>> [match.value for match in parse('key3.*').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':{'key4':{'key5':{'id':3, 'name':'shouke'}}}})]
[{'key5': {'name': 'shouke', 'id': 3}}]
>>> [match.value for match in parse('key3.*').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}, {'id':4, 'name':'keshou'}]})]
[]
>>> [match.value for match in parse('key1, key2, key3').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}, {'id':4, 'name':'kesh
[{'id': 1}, {'id': 2}, [{'id': 3}, {'name': 'shouke'}, {'name': 'keshou', 'id': 4}]]
>>> [match.value for match in parse('*.*[*]').find({'root':{'key':[{'id':'tizza'}, {'name':'hizza'}]}})]
[{'id': 'tizza'}, {'name': 'hizza'}]
field , field 指定多个字段
>>> [match.value for match in parse('key1, key2, key3').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}, {'id':4, 'name':'keshou'}]
[{'id': 1}, {'id': 2}, [{'id': 3}, {'name': 'shouke'}, {'name': 'keshou', 'id': 4}]]
数组索引说明(idx)
[n] 数组索引
[start?:end?] 含义同python的数组切片,注意:数组索引不包含end,可以不指定start, end,或者两者之一
[*] 任意索引,表示返回整个数组元素,等同于[:]
例子
[*]
[match.value for match in parse('key3[*]').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}, {'id':4, 'name':'keshou'}]})]
[{'id': 3}, {'name': 'shouke'}, {'name': 'keshou', 'id': 4}]
[start?:end?]
>>> [match.value for match in parse('key3[0:1]').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}, {'id':4, 'name':'keshou'}]})]
[{'id': 3}]
>>> [match.value for match in parse('key3[0:]').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}, {'id':4, 'name':'keshou'}]})]
[{'id': 3}, {'name': 'shouke'}, {'name': 'keshou', 'id': 4}]
>>> [match.value for match in parse('key3[:1]').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}, {'id':4, 'name':'keshou'}]})]
[{'id': 3}]
>>> [match.value for match in parse('key3[:]').find({'key1':{'id': 1}, 'key2':{'id': 2}, 'key3':[{'id':3}, {'name':'shouke'}, {'id':4, 'name':'keshou'}]})]
[{'id': 3}, {'name': 'shouke'}, {'name': 'keshou', 'id': 4}]
>>>
更多功能参考官方文档
参考链接
https://pypi.org/project/jsonpath-ng/#files
作者:授客
微信/QQ:1033553122
全国软件测试QQ交流群:7156436
Git地址:https://gitee.com/ishouke
友情提示:限于时间仓促,文中可能存在错误,欢迎指正、评论!
作者五行缺钱,如果觉得文章对您有帮助,请扫描下边的二维码打赏作者,金额随意,您的支持将是我继续创作的源动力,打赏后如有任何疑问,请联系我!!!
微信打赏
支付宝打赏 全国软件测试交流QQ群