JSONPath,一个事半功倍的查找取数工具

目录

前言

JSONPath介绍

操作项

筛选器运算符

函数

样本

使用说明

延伸


前言

日常在书写用例断言的时候,经常会遇到这样的场景:从结果中提取关键属性用于后续业务或者断言。

一般遇到这类情况,处理方式基本都跟剥洋葱一样,遇到数组/集合,一层层循环读取,遇到对象套对象,一层层对象点属性点出来。对于要从复杂的结果里面提取关键数据,要写的解析代码很多,有没有办法精简这种提取操作呢?

群众的智慧是强大的,所以结论肯定是有的,而且已经出现很久了,它就是 jmeter 自带的后置处理器之JSON提取器里使用到的库:JSONPath

JSONPath介绍

JSONPath是由Stefan Goessner在2007年左右提出的概念,它是受到XPath(XML路径语言)的启发,设计用于从JSON文档中抽取或筛选指定数据的一种表达式语言。类似于XPath作用于XML文档,JSONPath允许开发者通过特定路径语法来选取JSON对象中的特定部分。

它解决了哪些问题呢?

  1. 零脚本编写,可直接在客户端完成从 JSON 结构中查找和提取数据

  2. 减少和服务端的交互,减少服务器响应带宽的使用

随着语言的发展和JSON 使用场景的不断丰富,目前 JSONPath 已经支持了很多主流语言,如java,js,groovy,php,go  等;

下面以 java 语言为例,举例说明。

操作项

操作项描述
$根元素,所以表达式的开头
@筛选器谓词正在处理的当前节点
*通配符。在需要名称或数字的任何地方可用
..深度扫描。在需要名称的任何地方都可用
.点符号子项,如 $.name
['' (, '')]括号内标注的一个或多个子项
[(,)]数组索引或索引
[start:end]数组切片运算符
[?()]筛选表达式。表达式的计算结果必须为布尔值

筛选器运算符

运算符描述
==left 等于 right(请注意,1 不等于“1”)
!=left 不等于 right
<左边小于右边
<=left 小于或等于 right
>left 大于 right
>=left 大于或等于 right
=~left 匹配正则表达式 [?(@.name =~ /foo.*?/i)]
inleft 存在于右边 [?(@.size 在 ['S', 'M'])] 中
ninleft 在 right 中不存在
subsetofleft 是 right [?(@.sizes 子集 ['S', 'M', 'L'])]
anyofleft 与 right 有交点 [?(@.sizes anyof ['M', 'L'])]
noneof左边与右边没有交点 [?(@.sizes noneof ['M', 'L'])]
sizeleft 的大小(数组或字符串)应与 right 匹配
emptyleft(数组或字符串)应为空

函数

运算符输出类型
min()Double
max()Double
avg()Double
stddev()Double
length()Integer
sum()Double
keys()Set
concat(X)like input
append(X)like input
first()Depends on the array
last()Depends on the array
index(X)Depends on the array

样本

{ "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
    }
  },
  "expensive": 10
}

使用说明

JsonPath使用方式结果
$.store.book[*].author返回书店中所有图书的作者
$..author所有作者
$.store.*返回书店中所有的东西,不仅包括书,还有其他物品,比如自行车
$.store..price返回书店中所有物品的价格
$..book[2]第三本图书
$..book[-2]倒数第二本书
$..book[0,1]前两本书
$..book[:2]从索引 0(含)到索引 2(不含)的所有图书
$..book[1:2]从索引 1(含)到索引 2(不含)的所有图书
$..book[-2:]最后两本书
$..book[2:]从索引 2(含)到最后的所有书籍
$..book[?(@.isbn)]所有带有 ISBN 编号的图书
$.store.book[?(@.price == 10)]返回店内价格等于10元的所有图书
$.store.book[?(@.price < 10)]返回店内价格小于10元的所有图书
$..book[?(@.price <= 10)]返回店内价格小于10元的所有图书
$..book[?(@.author =~ /.*REES/i)]所有与正则表达式匹配的书籍(忽略大小写)
$..*把一切东西都返回
$..book.length()书籍数量

还有一种很奇怪的用法:$..book[?(@.price < $['expensive'])] 返回店内所有不“贵”的书。这里的 $['expensive'] 是获取这个属性对应的值,即$..book[?(@.price<10)]

基础语法到此已介绍完毕,快去实践起来吧。

延伸

  1. 体验工具,网页搜索JSONPATH在线验证,注意有些工具的语法会有些许出入

  2. 如何引入工程里面简化取数逻辑代码呢?通过pom导入jar包,注意jar的版本,不同的版本对应的服务是存在差异的

  3. 也可在自己的工具里面,提供书写表达式窗口来简化自己的工具

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值