jsonpath


jsonpath

一、RFC 9535标准与JSONPath Plus的区别

特性 RFC 9535(标准规范) JSONPath Plus(扩展实现)
定位 官方标准语法,定义基础操作符和语义 兼容RFC 9535的超集,额外增强功能
动态执行 无动态代码执行机制(如eval 支持evalFunction动态执行,但存在安全风险(如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[~]:返回所有书籍的属性名(如titleprice
@type() 类型选择器(如@integer() $..numbers[?(@integer())]:筛选整数值
多路径查询 单表达式查询多个路径 $['title','price']:同时提取书名和价格

3. 特殊语法与函数

语法 描述 示例
函数调用 在过滤器中调用内置函数 $..book[?length(@.authors) > 1]:作者数>1的书籍
逻辑运算符 支持&&、`
正则匹配 =~操作符 $..book[?(@.title =~ /^The.*/)]:匹配以”The”开头的书名

三、适用场景建议

  1. RFC 9535
    • 需严格跨语言兼容的场景(如Go的theory-jsonpath库)
    • 安全性要求高,避免动态代码执行风险
  2. 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


文章作者: 读序
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 读序 !
  目录