jsonpath 语法介绍

本文围绕Python接口测试中JSONPath的使用展开。详细介绍了JSONPath表达式中各字符的含义,如$、.、..等,还说明了区间范围筛选的规则,包括多条件使用&&等。此外,列举了JSON Path在Java、PHP、JavaScript等多种语言中的实现及项目地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录

  • 前言

  • 一、对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实现的项目名称都差不多。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值