惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
T
The Exploit Database - CXSecurity.com
P
Proofpoint News Feed
Scott Helme
Scott Helme
NISL@THU
NISL@THU
Cisco Talos Blog
Cisco Talos Blog
C
Cybersecurity and Infrastructure Security Agency CISA
AWS News Blog
AWS News Blog
V
Vulnerabilities – Threatpost
J
Java Code Geeks
U
Unit 42
The GitHub Blog
The GitHub Blog
H
Help Net Security
T
Tenable Blog
aimingoo的专栏
aimingoo的专栏
Jina AI
Jina AI
Spread Privacy
Spread Privacy
Apple Machine Learning Research
Apple Machine Learning Research
人人都是产品经理
人人都是产品经理
L
Lohrmann on Cybersecurity
T
Threatpost
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Engineering at Meta
Engineering at Meta
A
About on SuperTechFans
I
InfoQ
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog
L
LINUX DO - 最新话题
K
Kaspersky official blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Threat Research - Cisco Blogs
C
Check Point Blog
T
The Blog of Author Tim Ferriss
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
Help Net Security
Help Net Security
Google DeepMind News
Google DeepMind News
A
Arctic Wolf
Y
Y Combinator Blog
N
News | PayPal Newsroom
M
MIT News - Artificial intelligence
Latest news
Latest news
H
Hacker News: Front Page
Blog — PlanetScale
Blog — PlanetScale
腾讯CDC
I
Intezer
爱范儿
爱范儿
F
Fortinet All Blogs
P
Palo Alto Networks Blog
C
CERT Recently Published Vulnerability Notes

博客园 - 漫思

python使用.env构建开发和生产环境 python项目的构建 nodejs构建CICD时的思考  成为 AI 智能体工程师的 10 个步骤 es6的 yield python 中的 yield 笔记本的A壳 thinkpad 更换 reduce() in Python python的字段赋值和取值的操作 python的语法类似于lodash分组展开,合并分组操作 SelectMany C# lodash 数组的常用做法 lodash里面的常用方法 技术的边界 Reduce 和 Transduce 的含义 尤雨溪创办的 VoidZero 官宣加入 Cloudflare,前端 Vite 等保持开源 Ramda 函数库参考教程 ramda es 数组的方法 flatmap map object.entity的教程 Map与FlatMap:在数据处理中的区别与联系 flat、flatmap与map的用法区别1 flat、flatmap与map的用法区别 AI不是从天而降,它经历了七十年三起三落:读懂AI的第三课 Agent 17 种架构模式 分析 & 思考 只有踩过坑才懂:前端生成唯一 ID,别用 Date.now ()了!试试它crypto.randomUUID() FastAPI python并发 代码是 AI 写的,生产事故谁背锅? AI Agent 走出 Demo 幻觉的唯一解药:Harness Engineering 高管的 AI 精神病 小米开源可控视频音效生成模型 ControlFoley ​IBM 联合红帽投资 50 亿美元:帮助企业确保开源软件安全 国家大基金领投 DeepSeek,首轮融资投前估值 450 亿美元 SpaceX 自研 AI 训练栈 V1.0 接近完工:用 C 重写、适配 22 万块 GB300 GPU 高管的 AI 精神病 - 漫思 做一款企业真正敢用的AI测试应用,到底有多难?究竟难在哪? - 漫思 工良吐槽篇:万字长文细说 AI 落地之笑谈 koarouter的路由基本能力 7. 简单语句 class-validator class- @koa/router 分路由 这是我见过的最好的koa2 classvalidate typeorm的能力 HLS.js destroy时会取消请求吗 从入门到精通:2025年本体管理工具选型指南,8款工具助你驾驭语义网络 一文入门智能体:dify 超快速构建AI agent C# 15 类型系统改进:Union Types skill网站 应无所住,而生其心 process.stdin.isTTY 谷歌学术走过风雨十年 听创始人畅谈苦辣酸甜 - 漫思 process.stdin.isTTY 是false的具体情况 asyncio 较为复杂的demo asyncio 简单demo python Annotated 独家解读:淘宝使用 Node.js 的 TypeScript 多场景开发和实践 mac uv 使用 Python 包管理工具 uv 使用教程 Python依赖管理新标杆:UV工具安装与实战指南 python的uv lobehubui python的enum通过int进行初始化 python的枚举类型 深度拆解:AI 智能体 Harness 的构造【译】 LlamaIndex是什么?LlamaIndex综述!看这一篇就够了! python和langchain的简单教程 nodejs的顶尖开源项目 基础Pydantic+TypedDict+Annotated +Dataclass 深度解析Python结构化数据工具:dataclass、Pydantic Model与TypedDict 被 LangChain 全家桶搞晕了?LangGraph、LangSmith、LangFlow 一文读懂 - 漫思 谁才是企业级开源平台的优选?OpenCSG与Dify、Coze、Langflow、Ollama 的差异化之路 四大框架全景解析:LangChain、LangGraph、DeepAgent、LangFlow 测试数据管理方式对比:dict vs dataclass vs TypedDict 革命性的写作:MDX 让你的 Markdown 全面动起来 Python - pydantic 入门介绍与 Models 的简单使用 欢迎使用 Pydantic¶ python模块导入 Python 里通常说“数组切片”,大多数时候指的是列表切片。基本格式是: 自定义hook的写法 Python 遍历字典的8种方法 python基础教程 or的简单用法 C# 15 引入了 联合类型 asyncio的基础理论 flask配置热更新 Form.Item 无法直接绑定两个 name Form.Item 的双向翻译官:getValueFromEvent 与 getValueProps Knex.js入门指南:Node.js最强大的SQL查询构建器 knex.js1 Knex.js C#多线程Thread.Join()的详解 Pretext:值得关注的文本排版引擎 Flask入门(四):Flask静态文件及配置 【高并发】消息队列思路 为何高并发系统中都要使用消息队列?这次彻底懂了! Node.js 消息队列应用:RabbitMQ、Kafka 与处理高并发任务 大文件上传下载处理方案-断点续传,秒传,分片,合并 Node.js 缓存策略优化:Redis、Memcached 与本地缓存实现 .NET开发者的救星:8个让你告别996的高效库 别再吹牛了,100% Vibe Coding 存在无法自洽的逻辑漏洞!
RFC 9535:JSONPath 的标准化之路
漫思 · 2026-04-09 · via 博客园 - 漫思

从 Stefan Gössner 2007 年的博客文章,到 2024 年正式成为 IETF 标准,JSONPath 走过了 17 年的标准化历程。本文带你深入了解 RFC 9535 的核心特性,并用 snack4-jsonpath 实战演示。

1. 为什么需要 JSONPath?

在 JSON 统治 API 世界的今天,我们几乎每天都在处理 JSON 数据。你是否遇到过这样的场景:

  • 从复杂的嵌套 JSON 中提取特定字段
  • 在多层嵌套的数组中筛选符合条件的元素
  • 对 API 返回的 JSON 进行灵活的数据转换

传统的方案要么需要编写大量代码遍历解析,要么依赖不兼容的各种实现。RFC 9535 的出现,终于结束了这种混乱局面。

2. RFC 9535 是什么?

RFC 9535 是 IETF(互联网工程任务组)于 2024 年 2 月正式发布的标准规范,全称:

JSONPath: Query Expressions for JSON

即「用于 JSON 的查询表达式」

该规范由三位作者共同编写:

  • Stefan Gössner — JSONPath 的创始人,早在 2007 年就提出了这一概念
  • Glyn Normington — RFC 编辑
  • Carsten Bormann — RFC 编辑

核心定义

RFC 9535 的核心可以概括为:

JSONPath 定义了一种字符串语法,用于从给定的 JSON 值中选择和提取 JSON 值。

简单来说,JSONPath 就是 JSON 的「XPath」——用类似路径表达式的方式查询 JSON 数据。

3. JSONPath vs 其他方案

标准化 RFC 9535 (2024) AWS 标准 RFC 6901 语法风格 类似 XPath 函数式 路径式 递归下降 ✅ .. ✅ ** ❌ 过滤能力 ✅ 强大 ✅ 强大 ❌ 简单查找 数组切片 ✅ ❌ ❌ 函数扩展 ✅ ✅ ❌
特性JSONPathJMESPathJSON Pointer

4. 核心语法一览

4.1 基本选择器

import org.noear.snack4.jsonpath.JsonPath;

String json = "{\"store\":{\"book\":[{\"author\":\"张三\",\"price\":8.95},{\"author\":\"李四\",\"price\":12.99}],\"bicycle\":{\"color\":\"red\",\"price\":399}}}";

4.2 通配符选择器

import org.noear.snack4.jsonpath.JsonPath;

// 选择所有子节点
JsonPath.select(json, "$.store.*");     // [数组, 对象] - store 下的所有成员

4.3 索引与数组切片

import org.noear.snack4.jsonpath.JsonPath;

// 索引选择(从 0 开始)
JsonPath.select(json, "$.store.book[0]");      // 第一本书
JsonPath.select(json, "$.store.book[-1]");     

4.4 递归下降 ..

这是 JSONPath 最强大的特性之一:

// 递归查找所有 author 字段
JsonPath.select(json, "$..author");     // ["张三", "李四"]

// 递归查找所有 price 字段
JsonPath.select(json, "$..price");      

4.5 过滤表达式 [?(...)]

RFC 9535 的过滤表达式使用 @ 代表当前节点:

// 基础比较
JsonPath.select(json, "$.store.book[?(@.price < 10)]");
// 结果:[{"author":"张三","price":8.95}]

// 字符串匹配
JsonPath.select(json, "$.store.book[?(@.author == '张三')]");

5. 函数扩展

RFC 9535 定义了标准函数扩展接口,snack4-jsonpath 完整实现:

5.1 内置函数

// length() - 获取长度
JsonPath.select(json, "length($.store.book)");    // 2

// count() - 计数(RFC 9535)
JsonPath.select(json, "count($.store.book)");      

5.2 字符串函数

// match() - 正则匹配(需启用完整模式)
JsonPath.select(json, "$.store.book[?match(@.author, '张.*')]");

// search() - 搜索(包含)
JsonPath.select(json, "$.store.book[?search(@.author, '三')]");

5.3 扩展聚合函数(Jayway 风格)

// min() / max() / avg() / sum()
String enhancedJson = "{\"prices\":[8.95,12.99]}";

JsonPath.select(enhancedJson, "$.prices.min()");  

6. 操作符详解

6.1 RFC 9535 标准操作符

// 比较操作符
@.price == 10      // 等于
@.price != 10      

6.2 扩展操作符(Jayway 风格)

// 正则匹配
@.author =~ /张.*/

// 集合操作
@.status in ["active", "pending"]
@.age nin [10, 20]              

7. 实际应用场景

7.1 API 响应解析

String apiResponse = """
{
  "code": 200,
  "data": {
    "users": [
      {"id": 1, "name": "Alice", "orders": [{"amount": 100}, {"amount": 200}]},
      {"id": 2, "name": "Bob", "orders": [{"amount": 150}]},
      {"id": 3, "name": "Charlie", "orders": []}
    ]
  }
}
""";

7.2 配置管理

String config = """
{
  "environments": {
    "dev": {"host": "localhost", "port": 8080},
    "staging": {"host": "staging.example.com", "port": 80},
    "prod": {"host": "prod.example.com", "port": 443, "ssl": true}
  },
  "current": "prod"
}
""";

7.3 数据校验与转换

// 提取并验证数据
String json = """
{
  "products": [
    {"name": "笔记本", "price": 4999, "stock": 100},
    {"name": "鼠标", "price": 99, "stock": 0}
  ]
}
""";

8. snack4-jsonpath 的双模式支持

snack4-jsonpath 同时支持 RFC 9535(IETF)模式和 Jayway 模式

8.1 模式差异

过滤行为 仅过滤子节点 递归过滤当前及子节点 .. 行为 RFC 标准语义 扩展语义 扩展操作符 支持(但不属于规范) ✅ 支持 扩展函数 支持(但不属于规范) ✅ 支持
特性RFC 9535 (默认)Jayway 模式

8.2 模式切换

import org.noear.snack4.Options;
import org.noear.snack4.Feature;

// RFC 9535 模式(默认)
JsonPath jp1 = JsonPath.parse("$.store.book[?(@.price > 10)]");

9. 语法速查表

$ 根节点 $@ 当前节点(过滤中) [?(@.price > 10)].key 子属性 $.store.book['key'] 括号记法 $['store']['book']* 通配符 $.store.*[0] 索引 $.book[0][-1] 末尾索引 $.book[-1][start:end] 切片 $.book[0:2][::step] 步长 $.book[::2]..key 递归下降 $..author[?()] 过滤表达式 [?(@.price < 10)], 多选 ['a','b']length() 长度函数 length($.items)count() 计数函数 count($.items)
语法说明示例

10. 与 XPath 的渊源

RFC 9535 附录 B 专门讨论了 JSONPath 与 XPath 的关系。

JSONPath 从 XPath 汲取了大量灵感:

/$ 文档根 ./@ 当前节点 ** 通配符 //.. 递归下降 [@attr='v'][?(@.attr=='v')] 过滤条件 path/a/bpath.a.b 子路径
XPathJSONPath含义

但 JSONPath 有自己的特色:

  • 更简洁的语法
  • 原生支持数组索引和切片
  • 针对 JSON 结构优化的查询语义

11. 标准化带来的好处

11.1 跨平台一致性

以前:同一段 JSONPath 表达式在不同库中可能有不同的行为。

现在:遵循 RFC 9535 的实现必须产生一致的输出。

11.2 正式测试套件

RFC 9535 配套了官方的 JSONPath Compliance Test Suite (CTS),实现者可以用它验证规范符合度。

11.3 安全考虑

RFC 9535 第 4 节专门讨论了安全问题:

  • 查询注入:恶意构造的查询可能耗尽资源
  • 路径遍历:类似文件系统的 .. 攻击
  • 正则表达式 DoS:复杂正则可能导致 ReDoS

snack4-jsonpath 通过以下方式应对:

// 可选的异常抑制
Options opts = new Options(Feature.JsonPath_SuppressExceptions);

12. 进阶技巧

12.1 链式查询

String json = """
{
  "users": [
    {"name": "Alice", "age": 30, "city": "Beijing"},
    {"name": "Bob", "age": 25, "city": "Shanghai"}
  ]
}
""";

12.2 路径归一化

// 获取归一化路径(Normalized Path)
String path = JsonPath.select(json, "$.users[0].name").getPath();

12.3 动态路径构建

// 解析后缓存,可重复使用
JsonPath path = JsonPath.parse("$.store.$.category[*]");

结语

RFC 9535 的发布标志着 JSONPath 进入了一个新的时代。从 2007 年的博客文章到 2024 年的 IETF 标准,这条路走了整整 17 年。

标准化的价值在于:

  • 开发者可以编写一次,到处运行
  • 工具厂商有了统一的规范遵循
  • 新实现有了明确的参考

snack4-jsonpath 作为 RFC 9535 的 Java 实现,不仅完整支持了标准规范,还通过 Jayway 兼容模式保留了扩展功能。无论你是需要标准兼容性还是扩展能力,都能找到合适的方案。

相关资源