摘要

  • RFC 9535 把 JSONPath 查询定义为:针对一份具体 JSON 值执行,得到由零个或多个节点组成的节点列表;每个节点在该值内恰有一条规范化路径。
  • $['approvals'][3] 可以准确指向此刻数组里的第四项。只要前面插入一项,同一字符串就可能指向另一条审批记录;位置唯一不等于身份持久。
  • 空节点列表、JSON null、重复选中与越界索引是不同事实。重要决策必须同时保存输入、查询、实现、结果与政策语义。

一条路径最容易制造的错觉,是它看起来像身份证号。

设想审批系统在上午九点收到一份 JSON。查询 $['approvals'][3] 命中王某的审批。五分钟后,系统把一条更早的补录插到数组开头。查询没有改,语法没有错,结果依然只有一个节点,但第四项已经变成李某。若缓存只保存路径而没有保存原始文档的摘要,“同一路径”就会被误读成“同一记录”。

这不是 RFC 9535 的缺陷。恰恰相反,标准把边界写得很清楚:JSONPath 针对一份查询参数——也就是一份具体 JSON 值——求值,返回节点列表。节点由值和它在这份输入中的位置共同构成。规范化路径能唯一标识该值中的节点,不能脱离这份值继续担保身份。

规范化解决的是坐标,不是沿革

规范化路径采用确定的方括号表示和转义方式,便于测试、结果比较、后处理和去重。它把“实现到底选中了哪里”变成可以复核的事实。即使原查询使用负数数组索引,规范化结果也会写成在当前数组长度下解析出的非负位置。这正说明坐标依赖具体输入。

RFC 6901 的 JSON Pointer 同样擅长在已知结构中定位值,规范化 JSONPath 也可以转换成 Pointer。两者都不会凭空得到文档版本、来源、模式版本或业务稳定 ID。结构一变,坐标与对象之间的联系就必须重新证明。

“没选到”至少有四种含义

RFC 9535 明确允许空节点列表。数组索引越界不会因为没有节点就自动成为执行错误;本段选不到,后续段自然继续为空。这与查询语法错误、执行超时、资源上限触发或解析失败完全不同。

空列表也不等于 JSON null。null 是一个确实存在的 JSON 值;缺少成员则没有节点。如果授权逻辑把两者都压成一个布尔假值,查询引擎可能完全合规,政策判断却已经失真。

同一节点被多次选中时,重复项会保留;count() 数的是节点数量,不是唯一值、唯一路径或唯一业务对象。某些查询允许多种顺序,实现甚至可以在两次求值中返回不同但都合规的排序。于是“取第一项”必须由应用另行定义顺序依据,不能借标准的名义把偶然顺序变成权威。

可互操作不等于可信

RFC 8259 规定 JSON,并警告重复成员名会损害互操作性;RFC 7493 的 I-JSON 进一步收紧输入;RFC 9485 为 match() 与 search() 提供共同正则表达式轮廓。IANA JSONPath 注册表 记录扩展函数,application/jsonpath 则标记查询文档的媒体类型。

这些约定让不同实现更有机会对同一份规整输入得出同样节点,却没有证明输入来自有权来源,也没有证明 owner 字段就是法律意义上的所有者、风险分数仍然新鲜,或某个标志足以触发不可逆动作。

邻近标准提供了一个具体例子:RFC 9537 用 JSONPath 定位 RDAP 响应中被遮蔽的字段。路径可以准确指出本次响应里的遮蔽位置,却不能还原隐藏值、证明遮蔽政策的授权,也不能证明上一版响应是什么。

安全边界从查询之前开始

RFC 9535 警告实现不得把任意查询片段交给宿主语言的 eval,应用也不能未经验证与转义就拼接成员名、索引或比较值。恶意查询或输入还可能让朴素递归下降消耗极高 CPU,甚至压垮调用栈。正确语法必须配合受限资源、明确失败模式与真正的 JSONPath 解析器。

RFC 3629 的 UTF-8 约束及 RFC 8949 所涉及的数据模型考虑有助于约束表示层,但决策证据链仍然是:源字节、解析后的 JSON 值、查询、实现与扩展、节点列表、应用解释、最终决定。RFC 9535 规范中间环节,前后两端必须由运行系统补齐。

给匹配结果配一张可重放回执

凡是用于访问控制、合规、路由政策或事件处置的查询,至少应保存:源字节或加密摘要与出处;解析器版本和重复成员处理政策;查询原文及媒体类型;插值变量验证前后的值;JSONPath 实现与版本;启用的扩展函数;超时和资源上限;以规范化路径表示的结果与可披露值;应用是否去重或排序;独立的顺序规则;模式与政策版本;决策者、时间和结果。

这张回执只能支持一个有边界的陈述:“实现 X 在限制条件 L 下,对摘要为 H 的输入执行查询 Q,返回这些位置。”如果要说“它和昨天是同一条记录”,还需要模式层的稳定 ID 和跨版本证据。

来源与边界

RFC 9535 的正式记录包括 HTML、纯文本、RFC Editor 信息页、Datatracker 页面、文档历史 和 勘误检索。工作组仓库 保存制定轨迹,跨实现比较项目 展示了共同规范为何必要。

本文还使用 RFC 8259、7493、9485、6901、8949、3629 与 9537,以及 IANA 注册表 和 媒体类型记录。治理视角来自 Heng Lu 关于现实层与符号权力、最小初始规范和运行代码优先的论述。

本文没有检查任何具名实现、服务、事故或攻击,也不声称 RFC 9535 有缺陷或某个组织正在误用 JSONPath。