跳到主要内容

JSONPath 查询测试实战, 从一堆 JSON 里精准取值

用 JSONPath 测试器从复杂 JSON 里取值, 讲清根 $ 子节点 数组 [*] 通配 递归 .. 这套语法, 配真实样例边写边看匹配结果, 调试接口响应和配置文件更省事。

发布于 作者 李雷
#JSONPath #JSON #查询 #开发工具 #调试

JSONPath 查询测试实战, 从一堆 JSON 里精准取值

接口返回一坨嵌套很深的 JSON, 你只想拿其中一个字段。打开编辑器写 for 循环逐层下钻, 或者拼一长串 data['list'][0]['user']['name'], 写到一半就乱了。JSONPath 就是为这件事生的, 一行表达式描述 "我要 JSON 里哪些位置的值", 引擎帮你遍历。这篇讲清楚它的语法, 并带你用一个真实样例边写边验证。

JSONPath 到底解决什么问题

JSONPath 之于 JSON, 类似 XPath 之于 XML, 是一种路径查询语言。它不改数据, 只负责 "选出来"。常见的三类场景:

  • 调试接口响应, curl 拿回几十 KB 的 JSON, 你只想确认某个字段有没有按预期返回。
  • 读配置文件, 想批量取出所有环境下某个键的值。
  • 数据提取, 从嵌套数组里挑出满足条件的若干条, 喂给下游脚本。

这些事都可以靠一行路径表达式搞定, 不用每次写一次性脚本。

五个核心语法记号

JSONPath 的语法不多, 记住这几个符号就能覆盖八成日常查询:

  • $ 表示根, 任何路径都从根开始, 整份 JSON 就是 $
  • .子节点 用点访问对象的字段, $.store 取 store 这个键。
  • [] 取数组元素或方括号取键名, $.book[0] 是第一本书, $['store'] 等价于 $.store
  • * 通配, $.store.book[*] 表示 book 数组里的每一个元素, 用它遍历整个数组。
  • .. 递归下钻, $..price 找出任意深度上所有叫 price 的字段, 不管它藏在第几层。

再加上过滤表达式 [?(@.price < 10)], 其中 @ 指当前正在遍历的那个数组元素, 你就能做条件筛选了。

一个真实输入输出例子

光说符号容易飘, 看一段经典的书店样例:

{
  "store": {
    "book": [
      { "title": "Sayings of the Century", "author": "Nigel Rees", "price": 8.95 },
      { "title": "Sword of Honour", "author": "Evelyn Waugh", "price": 12.99 },
      { "title": "Moby Dick", "author": "Herman Melville", "price": 8.99 }
    ]
  }
}

你想拿出所有作者名。写这条路径:

$.store.book[*].author

含义是, 从根 $ 进 store, 再进 book 数组, [*] 把数组里每个元素都遍历一遍, 最后取每个元素的 author 字段。匹配结果就是:

["Nigel Rees", "Evelyn Waugh", "Herman Melville"]

想换个口味, 只要 10 块以下的便宜书, 把表达式改成 $.store.book[?(@.price < 10)].title, 立刻命中 Sayings of the CenturyMoby Dick, 那本 12.99 的被过滤掉。整个过程不写一行代码。

边写边看匹配结果, 比脑补靠谱

我自己以前调接口, 总爱在脑子里推 "这条路径应该能取到", 然后真跑起来一片空。后来习惯改了, 先把响应粘进 JSONPath 查询测试器, 一边敲表达式一边看右侧实时高亮的匹配值和命中路径。哪一步选空了一眼就看出来, 是字段名大小写写错, 还是 .. 范围放太宽, 当场就改完了, 省下来回猜的时间。

实时反馈最大的好处是把 "调试" 变成 "试探"。你可以先写 $..price 看价格到底分布在哪几层, 再逐步收窄到 $.store.book[*].price, 路径是怎么一点点精确起来的, 屏幕上看得清清楚楚。

几个容易栽的坑

  • 过滤里漏写 @. 前缀。[?(price < 10)] 解析不过, 过滤的上下文是当前数组元素, 必须写成 [?(@.price < 10)]
  • 拿字符串跟数字比。如果 JSON 里 price 是带引号的 "8.95", 那 [?(@.price < 10)] 一条都不匹配, 因为字符串不会按数值比较。
  • .. 当成 "跳一层"。$..book 是 "任意深度所有叫 book 的字段", 如果 JSON 里好几处不相干的地方都叫 book, 会被一锅端出来, 需要时把完整前缀写全。

配合其他工具一起用

JSONPath 取值的前提是 JSON 本身格式合法。如果响应是压成一行的, 或者你怀疑括号没闭合, 先丢进 JSON 格式化工具 美化并校验一遍, 结构清楚了再写路径会顺很多。等路径在浏览器里验证通过, 那条表达式就能直接搬进你的代码或命令行里跑, 一次写对。

JSONPath 不是什么高深的东西, 五个符号加一个过滤器就够用了。真正费时间的从来不是语法, 而是面对深层嵌套时的反复试错。把试错搬到一个能实时看结果的地方, 这件事就快了。


Made by Toolora · Updated 2026-06-13