一、JsonPath介绍:
首先,JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript, Python, PHP 和 Java。直白点的话就是独立的可以配合多种语言进行匹配的目标值的一种类库,和jmeter中的jsonPath匹配方式很像。优点之一就是 数据可以通过交互方式从客户端上的JSON结构提取,不需要特殊的脚本
二、JSONPath 表达式
JSONPath 表达式总是引用 JSON 结构,就像 XPath 表达式与 XML 文档结合使用一样。由于 JSON 结构通常是匿名的并且不一定具有“根成员对象”,因此 JSONPath 假定$
分配给外层对象的抽象名称。
JSONPath表达式可以使用点符号
$.store.book[0].title
或括号
$['store']['book'][0]['title']
对于输入路径。内部或输出路径将始终转换为更通用的括号表示法。
JSONPath 允许通配符* 用于成员名称和数组索引。它借用了E4X的后代运算符 '..'和ECMASCRIPT 4的数组切片语法建议。[start:end:step]
底层脚本语言的表达式(<expr>)
可以用作显式名称或索引的替代方法,如
$.store.book[(@.length-1)].title
对当前对象使用符号“@”。通过如下语法支持过滤?(<boolean expr>)
表达式
$.store.book[?(@.price < 10)].title
这是 JSONPath 语法元素与其 XPath 对应元素的完整概述和并排比较。
路径 | JSON路径 | 描述 |
---|---|---|
/ | $ | 根对象/元素 |
. | @ | 当前对象/元素 |
/ | . 或者 [] | 子操作员 |
.. | 不适用 | 母运营商 |
// | .. | 递归下降。JSONPath 从 E4X 借用了这种语法。 |
* | * | 通配符。所有对象/元素,无论其名称如何。 |
@ | 不适用 | 属性访问。JSON 结构没有属性。 |
[] | [] | 下标运算符。XPath 使用它来迭代元素集合和谓词。在 Javascript 和 JSON 中,它是原生数组运算符。 |
| | [,] | XPath 中的联合运算符会产生节点集的组合。JSONPath 允许将备用名称或数组索引作为一个集合。 |
不适用 | [开始:结束:步骤] | 数组切片运算符借鉴自 ES4。 |
[] | ?() | 应用过滤器(脚本)表达式。 |
不适用 | () | 脚本表达式,使用底层脚本引擎。 |
() | 不适用 | 在 Xpath 中分组 |
XPath 提供的内容(非缩写语法、运算符和函数中的位置路径)比这里列出的要多得多。此外,下标运算符在 Xpath 和 JSONPath 中的工作方式存在显着差异。
- XPath 表达式中的方括号始终对先前路径片段产生的节点集进行操作。索引总是从 1 开始。
- 使用 JSONPath 方括号对前一个路径片段寻址的对象或数组进行操作。索引总是从 0 开始。
JSONPath 示例
让我们通过更多示例来练习 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
}
}
}
路径 | JSON路径 | 结果 |
---|---|---|
/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示例
import json
import jsonpath
d={
"error_code":0,
"stu_info":
[
{
"id":10086,
"name":"小芳",
"sex":"女",
"classname":"三年二班"
},
{
"id": 10000,
"name": "小龙",
"sex": "男",
"classname": "三年三班"
},
{
"id": 10001,
"name": "小黑",
"classname": "三年三班"
}
]
}
print(type(d))
name=d["stu_info"][0]["name"]
print(name)
# 模糊匹配 匹配所有学生name
data1=jsonpath.jsonpath(d,"$..name")
print("匹配所有学生name:",data1)
# 精确匹配
# 获取null的值 匹配第一个学生name
data3=jsonpath.jsonpath(d,"$.stu_info[0].name")
print("匹配第一个学生name:",data3)
# 匹配第一个学生name
data4=jsonpath.jsonpath(d,"$.stu_info[0]..name")
print("匹配第一个学生name:",data4)
#匹配前两个学生的信息
data=jsonpath.jsonpath(d,"$.stu_info[:2]")
print("匹配前两个学生的信息:",data)
data5=jsonpath.jsonpath(d,"$.stu_info[?(@.sex=='女')]")
print("匹配性别为女的学生信息:",data5)
data6=jsonpath.jsonpath(d,"$.stu_info[?(@.sex)]")
print("匹配包含性别列的学生信息:",data6)
注意
- 目前只允许在 JSONPath 表达式中使用单引号。
- JSONPath 位置内的脚本表达式目前不由
jsonPath
. 只有全局$
和局部@
符号通过简单的正则表达式扩展。 -
在不匹配的情况下
jsonPath
返回的替代方法可能是将来返回一个空数组。false