Skip to main content
CheckTown
开发工具

JSONPath:从 JSON 文档中提取数据的查询语言

发布于 阅读约 7 分钟
本文目录

什么是 JSONPath?

JSONPath 是一种用于从 JSON 文档中提取数据的查询语言。正如 XPath 用于遍历 XML 文档,JSONPath 借助简洁的表达式语法来遍历 JSON 结构。经过多年非正式规范的沉淀,它最终在 RFC 9535(2024 年 2 月)中被正式标准化。

JSONPath 表达式以 $(根元素)开头,通过点号表示法或方括号表示法遍历文档。该语言支持通配符、递归下降、数组切片和过滤表达式,因此仅用一个表达式就能提取深层嵌套的值。

JSONPath 语法

JSONPath 提供了多种运算符,用于遍历和过滤 JSON 结构。

  • 根($)——每个 JSONPath 表达式都以 $ 开头,表示 JSON 文档的根对象或根数组
  • 点号表示法($.store.book)——按名称访问子属性,类似于 JavaScript 的对象访问方式。点号分隔每一层嵌套。
  • 方括号表示法($['store']['book'])——使用带引号的属性名放在方括号中的另一种写法。当属性名包含特殊字符或空格时必须使用这种写法。
  • 通配符(*)——匹配当前层级的所有元素。$.store.* 返回 store 的所有直接子元素;$[*] 返回根数组的所有元素。
  • 递归下降(..)——在任意深度搜索所有后代节点。$..price 会查找文档中任意嵌套层级下的每一个 “price” 字段。
  • 数组切片([start:end:step])——选取数组元素的某个范围。$[0:3] 返回前三个元素;$[-2:] 返回最后两个;$[::2] 返回每隔一个的元素。

JSONPath 表达式示例

以下是一些实用示例,展示 JSONPath 表达式如何从真实的 JSON 结构中提取数据。

  • 提取嵌套值——$.users[0].name 获取第一个用户的姓名。$.config.database.host 获取一个深层嵌套的配置值。
  • 过滤数组——$.users[?(@.age > 18)] 返回所有年龄大于 18 的用户。$.products[?(@.price < 50)] 查找价格实惠的产品。过滤器使用 @ 来引用当前元素。
  • 多层级查询——$..author 返回任意深度的每一个 author 字段。$.store.book[*].title 返回所有书名。$.orders[*].items[*].sku 提取所有订单及其条目中的 SKU。

这些表达式可以组合起来创建强大的查询。例如,$.store.book[?(@.price < 10)].title 返回所有价格低于 10 的书籍的书名。

免费试用 —— 无需注册

测试 JSONPath 表达式 →

常见使用场景

凡是需要从 JSON 文档中查询或提取结构化数据的地方,都会用到 JSONPath。

  • 提取 API 响应——无需编写自定义解析代码,即可从复杂的 API 响应中提取特定字段。在编码之前,先针对样例响应测试表达式。
  • 解析配置——在 CI/CD 流水线、部署脚本和基础设施即代码工具中,从 JSON 配置文件里提取值
  • 日志分析——查询结构化的 JSON 日志,在海量日志文件中查找特定事件、错误模式或性能指标
  • 数据转换——在 ETL 流水线中使用 JSONPath,在导入/导出过程中选取、过滤并重塑 JSON 数据

JSONPath、JQ 与 JMESPath 对比

有多种查询语言以 JSON 文档为目标,各有不同的优势和生态支持。

  • JSONPath——标准查询语法(RFC 9535),在各类编程库中被广泛支持(Java、Python、JavaScript、PHP)。最适合简单的提取和过滤,不内置转换功能。
  • JQ——命令行 JSON 处理器,拥有强大的函数式语言。支持转换、计算和输出格式化。最适合 Shell 脚本编写和命令行数据处理。
  • JMESPath——被 AWS CLI 和 Boto3 使用的查询语言。语法比 JSONPath 更严格,并内置了函数。最适合 AWS 生态集成和程序化查询。

常见问题

JSONPath 的数组下标是从 0 开始还是从 1 开始?

JSONPath 采用从 0 开始的数组下标,与大多数编程语言一致。$[0] 返回第一个元素,$[1] 返回第二个,以此类推。负数下标从末尾开始计数:$[-1] 返回最后一个元素,$[-2] 返回倒数第二个。

JSONPath 中的过滤表达式是如何工作的?

过滤表达式使用 [?(expression)] 语法,其中 @ 引用当前正在求值的元素。你可以使用比较运算符(==、!=、<、>、<=、>=)、逻辑运算符(&& 和 ||)以及属性访问(例如 @.name)。示例:$[?(@.status == 'active')] 返回 status 等于 “active” 的元素。

所有 JSONPath 实现都兼容吗?

并非完全兼容。在 RFC 9535(2024 年)之前,JSONPath 没有正式标准,各实现之间存在差异。常见的差异包括过滤表达式语法、递归下降行为,以及对缺失属性的处理方式。RFC 9535 旨在统一行为,但较旧的库可能仍遵循不同的约定。请始终针对你具体使用的实现来测试表达式。

相关工具