python之jsonpath库
作者:YXN-python 阅读量:350 发布日期:2022-10-01
1. 基本概念
根节点:所有 JSONPath 表达式都以根节点 $ 开始。
点表示法:使用点 . 来访问子属性(适用于属性名是有效的标识符时)。
括号表示法:使用方括号 [] 来访问子属性(通用,适用于任何属性名)。
2. 基本运算符和语法
| 语法 | 描述 | 示例(假设 $ 是根) |
| $ | 根对象/元素。 | $ 代表整个 JSON。 |
| . 或 [] | 子运算符,用于访问属性。 | $.store.book 或 $[‘store’][‘book’] |
| .. | 递归下降。在任何深度扫描匹配名称的元素。 | $..author 查找所有 author 字段。 |
| * | 通配符。匹配所有对象或数组元素。 | $.store.book[*].author 所有书的作者。 |
| [,] | 并集运算符。获取多个字段或索引。 | $..[‘author’, ‘title’] 获取所有作者和标题。 |
| [start:end:step] | 数组切片。从数组中选取一个子集。 | $..book[0:2] 获取前两本书(索引 0 和 1)。 |
| ?() | 过滤器表达式。基于逻辑条件进行筛选。 | $..book[?(@.price < 10)] 获取价格低于 10 的书。 |
| @ | 在过滤器脚本中代表当前节点。 | 在 ?(@.isbn) 中,@ 代表正在被判断的 book 对象。 |
JSONPath 语法元素与其 XPath 对应元素的完整概述和并排比较
| Xpath | JsonPath | 描述 |
| / | $ | 根节点 |
| . | @ | 现行节点 |
| / | .or[] | 取子节点 |
| .. | n/a | 就是不管位置,选择所有符合条件的条件 |
| * | * | 匹配所有元素节点 |
| [] | [] | 迭代器标示(可以在里面做简单的迭代操作,如数组下标,根据内容选值等) |
| | | [,] | 支持迭代器中做多选 |
| [] | ?() | 支持过滤操作 |
| n/a | () | 支持表达式计算 |
| () | n/a | 分组, Json Path不支持 |
此外,下标运算符在 Xpath 和 JSONPath 中的工作方式也存在显着差异。
- XPath 表达式中的方括号始终在节点集由上一个路径片段产生。索引始终以 1 开头。
- 使用 JSONPath 方括号操作在对象或数组由上一个路径片段寻址。索引始终以 0 开头。
3.详细用法和示例
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 结构的所有成员 |
问题
- 目前 JSONPath 表达式中只允许使用单引号。
- JSONPath 位置内的脚本表达式当前未由 `jsonPath`.只有全球 `$` 和本地 `@` 符号通过简单的正则表达式进行扩展。
- 替代 `jsonPath` 返回 `false` 在以下情况下 *无匹配* 将来可能会返回一个空数组。
举例:
url = ''
obj = json.loads(requests.get(url).text)
singer = jsonpath.jsonpath(obj, '$.result.songs[*].artists[0].name')
更多示例
a. 访问属性
- $.store.book:获取 store 下的 book 数组。
- $.store.bicycle.color:获取自行车的颜色("red")。
- $[‘store’][‘bicycle’][‘color’]:同上,使用括号表示法。当属性名包含特殊字符(如空格、连字符)时非常有用,例如 $[‘my-attribute’]。
b. 递归下降 (..)
- $..author:查找文档中所有 author 字段的值。
- 结果:[“Nigel Rees”, “Herman Melville”, “J. R. R. Tolkien”]
- $..book..title:查找所有 book 对象(无论在何处)的 title 字段。
- $..price:查找所有 price 字段的值。
- 结果:[8.95, 8.99, 22.99, 19.95]
c. 通配符 (*)
- $.store.*:获取 store 下的所有直接子元素(book 数组和 bicycle 对象)。
- $.store.book[*].title:获取所有书的标题。
- 结果:[“Sayings of the Century”, “Moby Dick”, “The Lord of the Rings”]
d. 数组索引
- 从 0 开始。
- $.store.book[0]:获取第一本书。
- $.store.book[-1]:获取最后一本书。
- $.store.book[0,2] 或 $.store.book[0,2]:获取第一本和第三本书(索引 0 和 2)。
e. 数组切片 ([start:end:step])
- end 索引是排他的(不包含)。
- $.store.book[0:2]:获取索引 0 到 1 的书(前两本)。
- $.store.book[:2]:同上,start 默认为 0。
- $.store.book[1:]:获取从索引 1 开始到末尾的所有书。
- $.store.book[-2:]:获取最后两本书。
- $.store.book[::2]:每隔一本取一本(索引 0 和 2)。
f. 过滤器表达式 (?())
过滤器是 JSONPath 最强大的功能之一,用于根据条件筛选数组元素。
- 存在性检查:$..book[?(@.isbn)]
- 描述:获取所有包含 isbn 字段的书。
- 数值比较:$..book[?(@.price < 10)]
- 描述:获取所有价格低于 10 的书。
- 逻辑运算符:可以使用 &&(与),||(或),!(非)。
- $..book[?(@.price < 10 && @.category == ‘fiction’)]:获取价格低于 10 的虚构类书籍。
- $..book[?(@.category == ‘reference’ || @.price > 20)]:获取参考类或价格高于 20 的书籍。
- 基于子属性的过滤:$..book[?(@.author =~ /Tolkien/i)](注意:正则表达式支持并非所有实现都具备)
- 描述:获取作者名包含 “Tolkien” 的书(不区分大小写)。
YXN-python
2022-10-01