jsonpath
一、RFC 9535标准与JSONPath Plus的区别
特性 |
RFC 9535(标准规范) |
JSONPath Plus(扩展实现) |
定位 |
官方标准语法,定义基础操作符和语义 |
兼容RFC 9535的超集,额外增强功能 |
动态执行 |
无动态代码执行机制(如eval ) |
支持eval 或Function 动态执行,但存在安全风险(如CVE-2025-1302) |
扩展语法 |
仅支持基础操作符(如$ 、@ 、* 等) |
新增父项操作符^ 、属性名操作符~ 、类型选择器(如@integer() ) |
沙箱隔离 |
无沙箱要求 |
需依赖vm2 等沙箱模块隔离,否则易逃逸执行系统命令 |
适用场景 |
需严格兼容标准的场景(如跨语言库) |
需高级查询或数据修改的场景(如复杂过滤、原型链操作) |
二、具体JSONPath语法规则及示例
1. 基础语法(RFC 9535与JSONPath Plus共用)
语法 |
描述 |
示例 |
$ |
根节点标识符 |
$.store.book :根节点下的store.book 属性 |
@ |
当前节点(仅限过滤器内) |
?(@.price > 10) :筛选价格>10的项 |
.* 或[*] |
通配符,匹配所有子节点 |
$.store.* :获取store 下所有属性 |
.. |
递归下降,搜索所有层级 |
$..title :提取任意层级的title 字段 |
[start:end] |
数组切片(左闭右开) |
$.book[0:2] :获取前两本书 |
?() |
过滤器表达式 |
$..book[?(@.category=='fiction')] :筛选类别为小说的书 |
2. JSONPath Plus扩展语法
语法 |
描述 |
示例 |
^ |
获取父节点 |
$..book[?(@.price>15)]^ :价格>15的书籍的父对象 |
~ |
获取属性名 |
$..book[~] :返回所有书籍的属性名(如title 、price ) |
@type() |
类型选择器(如@integer() ) |
$..numbers[?(@integer())] :筛选整数值 |
多路径查询 |
单表达式查询多个路径 |
$['title','price'] :同时提取书名和价格 |
3. 特殊语法与函数
语法 |
描述 |
示例 |
函数调用 |
在过滤器中调用内置函数 |
$..book[?length(@.authors) > 1] :作者数>1的书籍 |
逻辑运算符 |
支持&& 、` |
|
正则匹配 |
=~ 操作符 |
$..book[?(@.title =~ /^The.*/)] :匹配以”The”开头的书名 |
三、适用场景建议
- RFC 9535
- 需严格跨语言兼容的场景(如Go的theory-jsonpath库)
- 安全性要求高,避免动态代码执行风险
- JSONPath Plus
- 复杂数据处理:如递归获取父节点、动态属性名提取
- 数据修改:支持action: ‘set’直接更新JSON值
- 注意:需禁用动态执行或强化沙箱(如配置vm2隔离require)
💡 实际开发提示:优先使用RFC 9535保证安全性和兼容性;若需高级功能(如多路径查询),可选用JSONPath Plus并严格校验输入表达式
JsonPath可在Central Maven存储库中找到。 Maven用户将其添加到您的POM。
com.jayway.jsonpath
json-path
2.2.0
操作符
操作 |
说明 |
$ |
查询根元素。这将启动所有路径表达式。 |
@ |
当前节点由过滤谓词处理。 |
* |
通配符,必要时可用任何地方的名称或数字。 |
.. |
深层扫描。 必要时在任何地方可以使用名称。 |
.<name> |
点,表示子节点 |
['<name>' (, '<name>')] |
括号表示子项 |
[<number> (, <number>)] |
数组索引或索引 |
[start:end] |
数组切片操作 |
[?(<expression>)] |
过滤表达式。 表达式必须求值为一个布尔值。 |
函数
函数可以在路径的尾部调用,函数的输出是路径表达式的输出,该函数的输出是由函数本身所决定的。
函数 |
描述 |
输出 |
min() |
提供数字数组的最小值 |
Double |
max() |
提供数字数组的最大值 |
Double |
avg() |
提供数字数组的平均值 |
Double |
stddev() |
提供数字数组的标准偏差值 |
Double |
length() |
提供数组的长度 |
Integer |
过滤器运算符
过滤器是用于筛选数组的逻辑表达式。一个典型的过滤器将是[?(@.age > 18)],其中@表示正在处理的当前项目。 可以使用逻辑运算符&&和||创建更复杂的过滤器。 字符串文字必须用单引号或双引号括起来([?(@.color == ‘blue’)] 或者 [?(@.color == “blue”)]).
操作符 |
描述 |
== |
left等于right(注意1不等于’1’) |
!= |
不等于 |
< |
小于 |
<= |
小于等于 |
> |
大于 |
>= |
大于等于 |
=~ |
匹配正则表达式[?(@.name =~ /foo.*?/i)] |
in |
左边存在于右边 [?(@.size in [‘S’, ‘M’])] |
nin |
左边不存在于右边 |
size |
(数组或字符串)长度 |
empty |
(数组或字符串)为空 |
Java操作示例
{
"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 |
获取json中store下book下的所有author值 |
$..author |
获取所有json中所有author的值 |
$.store.* |
所有的东西,书籍和自行车 |
$.store..price |
获取json中store下所有price的值 |
$..book[2\] |
获取json中book数组的第3个值 |
$..book[-2\] |
倒数的第二本书 |
$..book[0,1\] |
前两本书 |
$..book[:2\] |
从索引0(包括)到索引2(排除)的所有图书 |
$..book[1:2\] |
从索引1(包括)到索引2(排除)的所有图书 |
$..book[-2:\] |
获取json中book数组的最后两个值 |
$..book[2:\] |
获取json中book数组的第3个到最后一个的区间值 |
$..book[?(@.isbn)\] |
获取json中book数组中包含isbn的所有值 |
$.store.book[?(@.price < 10)\] |
获取json中book数组中price<10的所有值 |
`$..book[?(@.price <= $[‘expensive’])] |
获取json中book数组中price<=expensive的所有值 |
$..book[?(@.author =~ /.*REES/i)\] |
获取json中book数组中的作者以REES结尾的所有值(REES不区分大小写) |
$..* |
逐层列出json中的所有值,层级由外到内 |
$..book.length() |
获取json中book数组的长度 |
工具网站:http://jsonpath.com/
GitHub:https://github.com/json-path/JsonPath