认识JSONPath
JsonPath 同 JSON 的关系,正如 XPath 与 XML 的关系一样。JsonPath 是设计来作为 JSON 的路径语言,用于确定 JSON 文档中某部分位置的语言
原理
JsonPath 将 JSON 数据转换为 DOM 树状结构,并提供在数据结构树中寻找节点的能力。
JsonPath 使用路径表达式在 JSON文档(字符串)中选取节点,节点是通过沿着路径来选取的。路径由节点名组成,节点之间以"."分割,且路径必须是由根节点开始的完全绝对路径
JSONPath与Xpath对比
XPath提供的功能(此处未缩写的语法,运算符和函数的位置路径)比此处列出的要多得多。此外,下标运算符在Xpath和JSONPath中的工作方式存在显着差异。
XPath表达式中的方括号始终作用于由先前路径片段产生的节点集。索引始终以1开始。
使用JSONPath时,方括号可用于由先前路径片段寻址的对象或数组。索引始终以0开头。
官方网址
基础语法
NEW
﹀
﹀
﹀
操作符
符号 | 描述 |
---|---|
$ | 查询的根节点对象,用于表示一个json数据,可以是数组或对象 |
@ | 过滤器断言(filter predicate)处理的当前节点对象,类似于java中的this字段 |
* | 获取所有节点 |
. | 获取子节点 |
.. | 获取子节点 |
?() | 过滤器表达式,筛选操作 |
[start:end] | 数组片段,区间为[start,end),不包含end |
[A]或[A,B] | 迭代器下标,表示一个或多个数组下标 |
[‘’ (, ‘’)] | 表示一个或多个子节点 |
[ (, )] | 表示一个或多个数组下标 |
函数
名称 | 描述 | 输出 |
---|---|---|
min() | 获取数值类型数组的最小值 | Double |
max() | 获取数值类型数组的最大值 | Double |
avg() | 获取数值类型数组的平均值 | Double |
stddev() | 获取数值类型数组的标准差 | Double |
length() | 获取数值类型数组的长度 | Integer |
过滤器
过滤器是用于过滤数组的逻辑表达式,一个通常的表达式形如:[?(@.age > 20)],可以通过逻辑表达式&&或||组合多个过滤器表达式,例如"$..book[?(@.price < 10 && @.isbn)]"
,字符串必须用单引号或双引号包围,例如"$..book[?(@.price < 10 && @.author == 'Herman Melville')]"
。
操作符 | 描述 |
---|---|
== | 等于符号,但数字1不等于字符1(note that 1 is not equal to ‘1’) |
!= | 不等于符号 |
< | 小于符号 |
<= | 小于等于符号 |
> | 大于符号 |
>= | 大于等于符号 |
=~ | 判断是否符合正则表达式,例如[?(@.name =~ /foo.*?/i)] |
in | 所属符号,例如[?(@.size in [‘S’, ‘M’])] |
nin | 排除符号 |
size | (数组或字符串)长度 |
empty | (数组或字符串)为空 |
案例演示
”让我们通过更多示例来练习JSONPath表达式。我们从在代表书店的XML示例(原始XML文件)之后构建的简单JSON结构开始。
{ "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 } }}
解析方式对比
XPath | JSONPath | 结果 |
---|---|---|
/store/book/author | $.store.book[*].author | 商店中所有书籍的作者 |
//author | $..author | 所有作者 |
/store/* | $.store.* | 商店里所有的东西,包括一些书和一辆红色的自行车。 |
/store//price | $.store..price | 商店中所有商品的价格。 |
//book[3] | $..book[2] | 第三本书 |
//book[last()] | $..book[(@.length-1)] $..book[-1:] | 最后一本书。 |
//book[position()<3] | $..book[0,1] $..book[:2] | 前两本书 |
//book[isbn] | $..book[?(@.isbn)] | 过滤出所有具有isbn编号的书 |
//book[price<10] | $..book[?(@.price<10)] | 筛选所有价格低于10的书籍 |
//* | $..* | XML文档中的所有元素。JSON结构的所有成员。 |
$..book.length() | 获取json中book数组的长度 |
在线测试地址:http://jsonpath.com/
在Python中如何操作
python操作 安装:pip install jsonpath
import jsonpath# from jsonpath import jsonpathdic = { "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 } }}author_name = jsonpath.jsonpath(dic,"$..author") # 查询所有作者price = jsonpath.jsonpath(dic,"$..book[?(@.price < 10 && @.author == 'Herman Melville')]") # 查询书中单价小于10并且author名为Herman Melvilleprint(author_name)print(price)"""解析结果:['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'J. R. R. Tolkien'][{'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99}]"""