本文最初发表于择维士社区
JSONPath 语法
这篇文章中会介绍JSONPath的语法使用. JSON在后端通讯中非常常见,那么在多个单元测试或者集成测试中都需要对服务端返回内容做校验,验证. 而JSONPath可以很方便的提取完整JSON中的部分数据用于校验和验证目的.
JSONPath 标记
一个JSONPath指定了JSON对象中一个或者一组元素的路径. 使用.
点号分隔.或者[]
分割.
比如:
$.store.book[0].title
$['store']['book'][0]['title']
最开始的$
代表根对象或者根数组.$ 可以被省略. 比如$.foo.bar
可以是foo.bar
常见的语法表达如下:
表达式 | 描述 |
---|---|
$ | 根对象或数组 |
.property | 某个对象的属性. |
[n] | 数组的第n个对象 |
[i1,i2] | 返回指定索引i1,i2对象,返回是list |
..property | 递归查询包含某个属性的对象. 返回包含此property的列表list. |
* | 通配符address.* 返回address的所有属性. book[*] 返回book数组的所有对象. |
[?(expression)] | 表达式过滤. 返回满足表达式的对象或者数组. 返回是list. 后面有介绍. |
[(*expression*)] | 脚本表达式.比如 [(@.length-1)] 选择数组最后一个元素. length 是当前数组的属性 length . |
@ | 用于表达式过滤中指代当前正在处理的元素. |
注意点:
- JSONPath是大小写区分的.
- JSONPath中不像XMLPath中提供访问父亲兄弟节点的方法.
表达式过滤
过滤器是一串表达式用于过滤数组内容. 比如如下的表达式:
$.store.book[?(@.price < 10)]
@代表当前正在处理的对象或者元素. $可以访问当前对象外的属性.比如:
$.store.book[?(@.price < $.expensive)]
支持的操作符如下:
操作符 | 描述 |
---|---|
== | 左边值等于右边. |
!= | 左边值不等于右边. |
< | 左边值小于右边. |
<= | 左边值小于等于右边. |
> | 左边值大于右边. |
>= | 左边值大于等于右边. |
=~ | 左边匹配正则 [?(@.name =~ /foo.*?/i)] |
in | 左边值在列表中 [?(@.size in [‘S’, ‘M’])] |
nin | 左边值不在列表中 |
subsetof | 左边是右边的子集 [?(@.sizes subsetof [‘S’, ‘M’, ‘L’])] |
anyof | 左边与右边有交集 [?(@.sizes anyof [‘M’, ‘L’])] |
noneof | 左边与右边没有交集 [?(@.sizes noneof [‘M’, ‘L’])] |
size | 左边的字符串长度或者数组长度等于右边. |
empty | 左边的字符串或者数组应该为空 |
示例
假如有如下的示例数据:
{
"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 | Result |
---|---|
$.store.book[*].author | 所有book的作者 |
$..author | 所有作者 |
$.store.* | store下所有对象 |
$.store..price | 有价格的对象 |
$..book[2] | 第3本书 |
$..book[-2] | 倒数第2本书 |
$..book[?(@.isbn)] | 所有有isbn的书 |
$.store.book[?(@.price < 10)] | 所有价格低于10的书 |
$..book[?(@.price <= $['expensive'])] | 所有价格不贵的书 |
$..book[?(@.author =~ /.*REES/i)] | 所有满足正则的书(忽略大小写) |
$..* | 所有 |
$..book.length() | 书个数 |
测试JSONPath是否合法
可以使用这个测试网站 来测试.
参考
- 实现JSONPath 的java库