JSONPath 里两个点和一个星号有什么区别?

3 个讲解板块 · 关联 2 款站内工具 · 内容最后核对 2026-10-09

两个点是递归到任意深度,一个星号只看当前一层,混用就会捞到不该要的字段。

直接答案

先把语义分清楚:递归下降的写法会钻进任意深度的所有后代,只要字段名匹配就收集;单层通配只看当前这一层的直接子元素,不管是对象的值还是数组的元素。需要「不管它在哪儿,全都给我」时用前者,知道结构时应该把完整路径写出来。

还有两个几乎人人都会撞上的特性。第一,表达式永远返回一个列表,就算只命中一个值也包在数组里,各语言实现有的会自动拆包有的不会,换库时最容易出意外。第二,键名里含点、空格或连字符时必须用括号写法,点号写法永远选不到那种键——这不是 bug,是语法本身如此。

从接口拿来一份几层嵌套的响应,想取出所有出现的某个字段,随手写了递归下降的表达式,结果多出来几个不相干的值,排查半天才发现顶层还有同名字段。

JSONPath 的语法不多,但每一处细节都对应一个实际坑,值得一次记住。

1四个符号的实际语义

结构差异集中在下面这几组。

写法含义常见误用
单点加字段名取当前节点的直接子字段字段名含点或空格时选不到,必须改成括号写法
两个点递归到任意深度收集匹配字段大文档上慢,且会命中意料之外的层级
星号当前这一层的所有子元素以为它也是递归,其实只下一层
方括号加下标按位置取数组元素,从零开始以为是按名字取,或记成从 1 开始

与另一套常见的 XML 查询语言对照记忆:那套的索引从 1 开始、方括号作用于上一段产生的节点集;这套从 0 开始、方括号作用于上一段指向的那个对象或数组。

2返回值的三个反直觉点

这些细节决定了你拿到结果之后还得再处理多少。

结果永远是列表
只命中一个值也是长度为一的数组。各实现是否自动拆包不统一,换库时务必核对。
切片是半开区间
起始含、结束不含,步长可以取负值做倒序,但负步长的支持度在各实现间差异较大。
递归结果丢失来源
同一个字段名出现在多个层级时,返回的是扁平列表,单看值无法判断它原本属于哪一层。

3什么时候该收窄写法

递归下降很好用,但不该当成默认选项。

结构已知就写全路径
明确知道字段在哪一层时,把完整路径写出来,既快又不会误伤。
大文档慎用递归
递归会遍历整棵子树,文档越大开销越明显,接口返回的巨型响应尤其要注意。
过滤表达式中的当前元素
过滤条件里的符号指正在被判断的那个元素,写条件时别忘了用它而不是根。
规范已经落地
该查询语言已发布正式标准(2024 年 2 月),选型时可以对着标准核对实现的支持范围。

相关疑问

为什么结果外面总包着一层数组?

这类查询表达式的设计就是返回一组匹配节点,即使只命中一个也在集合里包装一次。需要标量时取结果数组的第一个元素即可。这一点与另一套主流查询语言的取向一致,但各语言实现是否自动拆包不统一,换库时要特别验证。

字段名里带点该怎么选?

必须改用括号写法,把整个键名作为字符串写进去。点号写法会把点解释成分层,所以永远匹配不到那个键,这是语法限制而不是实现缺陷。

递归下降为什么有时候很慢?

因为它是深度优先地遍历整棵子树,不是按索引直接定位。文档越大、嵌套越深,开销越明显。已知结构时改用完整路径能显著提速。

过滤表达式的条件写在哪一层?

过滤写在方括号里,条件里的符号指「正在被检查的那个元素」,也就是当前遍历到的数组元素或对象成员,不是文档根。根也可以参与比较,但需要用不同的写法显式引用。

内容标识:本页内容由人工智能辅助生成,并经人工核对与编辑。详见 人工智能生成内容标识说明。
内容说明:本页针对具体使用问题作答,方法步骤与数值由本站自行整理与复算,事实性内容以对应官方规范与文档为准。内容最后核对日期:2026-10-09。若发现错误,欢迎通过页脚反馈入口告知。