文章目录
-
一、对jsonpath的理解
-
(1)解释 . 和 $ 字符
-
(2)解释 ..字符:表示:递归匹配所有子元素,然而获取所有符合条件的内容(这个条件是跟在 ..后面)
-
(3)解释:[ ]字符:表示索引的取值
-
(4)解释:* 字符:表示:通配符,匹配下级节点(注意:这个的节点是指有键值对的节点,不是外层取名字的节点)
-
(5)解释:@ 字符:表示:当前元素下(节点下),相当于一种限定
-
(6)解释:?() 字符:表示:过滤操作(过滤表达式)
-
-
二、对于区间范围的筛选
-
(1)多条件的时候要用:&&
-
(2)价格等于某个值,要使用 ==
-
(3)如果要匹配某个节点的属性(也就是值),那么就要用 ==
-
(4)多条件的时候,先过滤再取值 ?@ [ ] ( ) 一起使用
-
(5)[ , ] 将多个结果拼接在一起(指定的字段放在一起)
-
(6)注意使用过滤条件某些返回值是一个字典
-
-
三、补充
-
四、哪里可以用的到呢?
前言
在使用Python做接口测试中需要获取json中的字段值,因此需要使用jsonpath里面的提取规则,所以特意学习了jsonpath中的语法。
一、对jsonpath的理解
注意:
jsonpath表达式:
$ ---->表示根节点.
. ---->一个点表示选择子节点
.. ---->两个点表示选择子孙节点(不考虑层级)
[ ] ---->方括号表示选择子节点或者选择索引
[a,b] ---->选择多个字段
@ ---->代表当前选中的节点(和条件过滤一起使用)
[?(过滤条件)] ---->通过条件过滤数据
在线运行地址:JSONPath Online EvaluatorAn online playground for JSONPathhttp://jsonpath.com/
下面有示例的json字符串
(1)解释 . 和 $ 字符
$.store.book 解释:$ 表示根节点,. 表示根节点下。(这个总体意思是:根节点下的store节点下的book节点)
注意:是跟在上一个节点下的下一个节点,这个下一个节点并不是里面的数据的键(这个理解可能有点绕)
举例1:
举例2:
解决访问不到例子:
附上代码:
import jsonpath
bb = {"no": "aa",
"data": {
"xyz":
{
"avc": {
"no1": {
"aa1": [1, 2, 3]
}
}
},
'age': {"ccc": [2, 3, 4],
"ddd": ["a",
"b",
{"eee": {"fff": "wwwwww"}}]
}
}
}
str_4 = "$..data.age.ddd" # 访问的这层列表是可以访问的
y = jsonpath.jsonpath(bb, str_4)
print(y)
str_5 = "$..data.age.ddd.eee" # 因为eee不是ddd的节点了,而是ddd这个列表里面的数据元素了,所以是无法访问的
z = jsonpath.jsonpath(bb, str_5)
print(z)
# 那么要解决这个访问不到的问题就有以下2中方法:
# 方法一:使用相对路径
str_6 = "$..data.age.ddd..eee"
z1 = jsonpath.jsonpath(bb, str_6)
print("这是方法一:", z1)
# 方法二:使用中括号[]进行选择
str_7 = "$..data.age.ddd.[eee]" # 这个也可以写成"$..data.age.ddd[.eee]"
z2 = jsonpath.jsonpath(bb, str_7)
print("这是方法二:", z2)
# 方法三:使用过滤操作,表达式,限定符@;
# 需要注意使用这种方法三提取出来的是一个完整的数据(键和值都会拿到,不会只拿到值)
str_8 = '$..data.age.ddd.[?(@.eee=={"fff":"wwwwww"})]' #
z3 = jsonpath.jsonpath(bb, str_8)
print("这是方法三:", z3)
(2)解释 ..字符:表示:递归匹配所有子元素,然而获取所有符合条件的内容(这个条件是跟在 ..后面)
$.store..price 解释:总体意思是:根节点下的store节点下的所有的子节点的price节点
(3)解释:[ ]字符:表示索引的取值
$.store.book[2] 解释:根节点下的store节点下的book节点中的第二个数据块
(4)解释:* 字符:表示:通配符,匹配下级节点(注意:这个的节点是指有键值对的节点,不是外层取名字的节点)
$.store.* 解释:根节点下的store节点下的book节点下的所有节点
(5)解释:@ 字符:表示:当前元素下(节点下),相当于一种限定
()字符:表示:里面写脚本表达式(也就是函数)
$..book[(@.length-1)] 解释:根节点下的book节点下的第四个节点(倒数第一个)。
[]里面放置索引,@表示:当前book这个元素,.表示这个元素下。length是一个函数,统计这个book元素下的个数。length-1:因为索引的取值是从0开始。
(6)解释:?() 字符:表示:过滤操作(过滤表达式)
过滤表达式,经常与@符号搭配使用
$..book[?(@.price<10)] 解释:根节点下的所有节点中的book节点,在book节点下过滤筛选出,在@限定下的当前节点中price<10的节点的数据
再次解释:@ . :表示限定当前节点;在此例子配置中表示:限定当前book节点
注意:使用限定@或者使用过滤?返回的值是一个字典,不是单独要的value
二、对于区间范围的筛选
(1)多条件的时候要用:&&
对于价格:20<price<22 注意价格的区间表示:要用&&这个符号(必须是2个&)
b = jsonpath.jsonpath(a, "$..book[?(@.price>20&&@.price<22)]")
print(b)
import jsonpath
a = {
"store": {
"book": [{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 21
}, {
"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
}
}
}
# 对于价格:20<price<22 注意价格的区间表示:要用&&这个符号(必须是2个&)
b = jsonpath.jsonpath(a, "$..book[?(@.price>20&&@.price<22)]")
print(b)
(2)价格等于某个值,要使用 ==
(3)如果要匹配某个节点的属性(也就是值),那么就要用 ==
参考:
JsonPath完全介绍及详细使用教程_字节自动化测试的博客-CSDN博客
JsonPath的使用及常用语法_jsonpath语法_我去刷碗啦的博客-CSDN博客
(4)多条件的时候,先过滤再取值 ?@ [ ] ( ) 一起使用
import jsonpath
a = {
"store": {
"book": [{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 21
}, {
"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
}
}
}
# # 对于价格:20<price<22 注意价格的区间表示:要用&&这个符号(必须是2个&)
# b = jsonpath.jsonpath(a, "$..book[?(@.price>20&&@.price<22)]")
# print(b)
# 价格等于某个值
# b = jsonpath.jsonpath(a, "$..book[?(@.price==22.99)]")
# print(b)
# 多条件时,先过滤再取值
# 先满足?(@.price>10&&@.category== 'fiction') 这个过滤条件后,再筛选title
b = jsonpath.jsonpath(a, "$..book[?(@.price>10&&@.category== 'fiction')].title")
print(b)
参考:
jsonpath中多条件提取和过滤提取_jsonpath 过滤_公子清羽的博客-CSDN博客
(5)[ , ] 将多个结果拼接在一起(指定的字段放在一起)
import jsonpath
a = {
"store": {
"book": [{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 21
}, {
"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
}
}
}
# # 对于价格:20<price<22 注意价格的区间表示:要用&&这个符号(必须是2个&)
# b = jsonpath.jsonpath(a, "$..book[?(@.price>20&&@.price<22)]")
# print(b)
# 价格等于某个值
# b = jsonpath.jsonpath(a, "$..book[?(@.price==22.99)]")
# print(b)
# 多条件时,先过滤再取值
# 先满足?(@.price>10&&@.category== 'fiction') 这个过滤条件后,再筛选title
# 多个指定的字段拼接在一起[,]
# "$..book.[title,price]" 意思是:book节点下的title和price字段
# 注意这里的book后面一定要带有. 表示:下一级
b = jsonpath.jsonpath(a, "$..book.[title,price]")
print(b)
(6)注意使用过滤条件某些返回值是一个字典
import jsonpath
a ={
"no": 0,
"data": {
"list": [
{
"ID": 259,
"CreatedAt": "2023-07-31T15:17:27.054022Z",
"UpdatedAt": "2023-07-31T15:17:27.054022Z",
"DeletedAt": None,
"Email": "",
"ProductId": 775,
"Sex": "f",
"LanguageCode": "en",
"Avatar": "/publicshare/avatar/20230731151726-38624-blk_comment_avatar.jpeg",
"CommentTime": "2023-07-31T15:17:25Z",
"Image": "",
"Images": [],
"Star": 4,
"Content": "This product is very beautiful_2023-07-31 23:17:25_2023-07-31 23:17:25!",
"UserName": "Basile Sawicki",
"Keywords": [],
"CreateType": 1,
"user_ip": "",
"CommentTimeRec": ""
},
{
"ID": 258,
"CreatedAt": "2023-07-31T15:16:27.433784Z",
"UpdatedAt": "2023-07-31T15:16:27.433784Z",
"DeletedAt": None,
"Email": "",
"ProductId": 775,
"Sex": "m",
"LanguageCode": "de",
"Avatar": "/publicshare/avatar/20230731151626-44617-blk_comment_avatar.jpeg",
"CommentTime": "2023-07-31T15:16:26Z",
"Image": "",
"Images": [],
"Star": 5,
"Content": "This product is very beautiful_2023-07-31 23:16:26_2023-07-31 23:16:26!",
"UserName": "Allyson Demarcq",
"Keywords": [],
"CreateType": 1,
"user_ip": "",
"CommentTimeRec": ""
},
{
"ID": 256,
"CreatedAt": "2023-07-31T14:41:40.229168Z",
"UpdatedAt": "2023-07-31T14:41:40.229168Z",
"DeletedAt": None,
"Email": "",
"ProductId": 775,
"Sex": "f",
"LanguageCode": "en",
"Avatar": "/publicshare/avatar/20230731144128-76617-blk_comment_avatar.jpeg",
"CommentTime": "2023-07-31T14:40:45Z",
"Image": "",
"Images": [],
"Star": 5,
"Content": "哈哈哈哈哈哈",
"UserName": "Meggie Strouss",
"Keywords": [],
"CreateType": 1,
"user_ip": "",
"CommentTimeRec": ""
},
{
"ID": 255,
"CreatedAt": "2023-07-31T02:33:41.994113Z",
"UpdatedAt": "2023-07-31T02:33:41.994113Z",
"DeletedAt": None,
"Email": "",
"ProductId": 775,
"Sex": "f",
"LanguageCode": "es",
"Avatar": "/publicshare/avatar/20230731023331-11746-驴1.png",
"CommentTime": "2023-07-31T02:33:17Z",
"Image": "",
"Images": [],
"Star": 5,
"Content": "几句话",
"UserName": "看接口进来看",
"Keywords": [],
"CreateType": 1,
"user_ip": "",
"CommentTimeRec": ""
}
],
"page": 1,
"total": 4
}
}
# 在这个list列表下面有很多个数据,每一个数据就是一个字典;所以"$..list[?(@.ID==258)]"返回的结果就是一个完整的字段
b = jsonpath.jsonpath(a, "$..list[?(@.ID==258)]")
print(b)
三、补充
这是一个非常经典的案例,你几乎可以在任何介绍JSON Path的地方看到它,但是很实用。
{ "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 Path 语法介绍和使用场景_小雨青年的博客-CSDN博客
参考一些博主:二、Python:Jsonpath语法、使用方法详细介绍及使用Python操作JSON代码示例_SteveRocket的博客-CSDN博客
DN博客
四、哪里可以用的到呢?
光有语法可操作意义不大,那么哪里可以用到JSON Path呢?
1. Java
Jayway JsonPath ,用于读取 JSON 文档的 Java DSL。
项目地址: https://github.com/json-path/JsonPath
2. PHP
JsonPath,JsonPath的PHP实现。
项目地址: https://github.com/Galbar/JsonPath-PHP
3. JavaScript
jsonpath, 使用 JSONPath 表达式查询 JavaScript 对象。 用于 Node.js 的强大/安全的 JSONPath 引擎。
项目地址: https://github.com/dchester/jsonpath
4. Python
jsonpath-ng,旨在符合标准的 Python JSONPath 的最终实现,包括算术和二进制比较运算符,并为元编程提供清晰的 AST。
项目地址:https://pypi.org/project/jsonpath-ng/
5. Go
Jsonpath,JsonPath的PHP实现。
项目地址:https://github.com/yalp/jsonpath
总结
JSON Path 作为一个语法标准,实现了对JSON的便捷读取。另外,各种语言的JSON Path实现的项目名称都差不多。