alltools.one
JSON
2025-07-04
8 min
alltools.one Team
JSONJSONPathQueryData ExtractionAPI

JSONPath 查询指南:像专家一样提取数据

JSONPath 是 JSON 的查询语言,类似于 XPath 之于 XML。当你处理来自 API 的复杂、深层嵌套的 JSON 响应时,JSONPath 让你无需编写循环和条件语句即可提取所需的数据。本指南涵盖了你需要的语法、运算符和实际模式。

为什么用 JSONPath?

考虑一个典型的嵌套数据 API 响应:

{
  "store": {
    "books": [
      { "title": "Clean Code", "author": "Robert Martin", "price": 32.99, "tags": ["programming", "best-practices"] },
      { "title": "Design Patterns", "author": "Gang of Four", "price": 44.99, "tags": ["programming", "architecture"] },
      { "title": "The Pragmatic Programmer", "author": "Hunt & Thomas", "price": 39.99, "tags": ["programming", "career"] }
    ],
    "music": [
      { "title": "Kind of Blue", "artist": "Miles Davis", "price": 12.99 }
    ]
  }
}

要获取所有书名,你可以写一个循环——或使用 JSONPath:$.store.books[*].title

基本语法

表达式描述
$根对象
.子运算符
..递归下降(搜索所有层级)
[*]通配符(所有元素)
[n]数组索引(从 0 开始)
[n,m]多个索引
[start:end:step]数组切片
[?()]过滤表达式
@当前元素(在过滤器中)

点号表示法 vs 括号表示法

两种表示法都可以访问属性,但特殊字符需要使用括号表示法:

# 点号表示法
$.store.books[0].title

# 括号表示法(等效)
$['store']['books'][0]['title']

# 带特殊字符的键必须使用括号
$['store']['price-range']

数组操作

索引

$.store.books[0]          # 第一本书
$.store.books[-1]         # 最后一本书
$.store.books[0,2]        # 第一和第三本书

切片

$.store.books[0:2]        # 前两本书(索引 0 和 1)
$.store.books[1:]         # 除第一本外的所有书
$.store.books[:2]         # 前两本书
$.store.books[::2]        # 每隔一本书

通配符

$.store.books[*].title    # 所有书名
$.store.*                 # 所有商店集合(books、music)
$..title                  # 任何深度的所有标题
$..price                  # 任何深度的所有价格

递归下降运算符(..)特别强大,可以提取不论层级位置的值。

过滤表达式

过滤器根据条件选择元素:

# 低于 $40 的书
$.store.books[?(@.price < 40)]

# 特定作者的书
$.store.books[?(@.author == 'Robert Martin')]

# 标签超过 2 个的书
$.store.books[?(@.tags.length > 2)]

# 有 'price' 属性的书
$.store.books[?(@.price)]

组合过滤器

# 低于 $40 且编程标签的书
$.store.books[?(@.price < 40 && @.tags[0] == 'programming')]

实际示例

从 API 响应中提取

GitHub API — 获取所有仓库名称:

$[*].name

天气 API — 获取今天的温度:

$.daily[0].temp.day

电商 API — 获取所有产品图片:

$.products[*].images[0].url

配置提取

Docker Compose — 获取所有服务名称:

$.services.*~

Package.json — 获取所有依赖名称:

$.dependencies.*~

JSONPath vs jq

JSONPath 和 jq 都是 JSON 查询工具,但服务于不同场景:

特性JSONPathjq
环境库、API命令行
语法受 XPath 启发自定义函数式
转换仅查询查询 + 转换
标准RFC 9535事实标准

命令行 JSON 处理用 jq 更强大。在应用中嵌入查询或在 Web 工具中使用时,JSONPath 支持更广泛。

使用我们的 JSON Path 浏览器 交互式尝试 JSONPath 表达式。粘贴你的 JSON,编写查询,即时查看结果。

实现示例

JavaScript (jsonpath-plus)

const { JSONPath } = require('jsonpath-plus');
const result = JSONPath({
  path: '$.store.books[?(@.price < 40)].title',
  json: data
});
// ["Clean Code", "The Pragmatic Programmer"]

Python (jsonpath-ng)

from jsonpath_ng import parse
expr = parse('$.store.books[*].title')
titles = [match.value for match in expr.find(data)]

RFC 9535:JSONPath 标准

2024 年 2 月,JSONPath 正式标准化为 RFC 9535。这解决了不同实现之间的历史不一致问题。标准化的关键行为:

  • 数组索引从 0 开始
  • 过滤表达式使用 @ 表示当前元素
  • 字符串比较区分大小写
  • 结果始终是匹配值的数组

选择 JSONPath 库时,优先选择支持 RFC 9535 的以获得一致的行为。

常见问题

JSONPath 和 JSON Pointer 有什么区别?

JSONPath 是一种查询语言,可以使用通配符和过滤器匹配多个值。JSON Pointer(RFC 6901)是一种简单的路径语法,精确寻址一个值:/store/books/0/title。需要搜索或过滤时使用 JSONPath;知道确切路径时使用 JSON Pointer。

JSONPath 可以修改 JSON 数据吗?

标准 JSONPath 是只读的——它提取但不修改数据。一些库扩展了 JSONPath 的设置/删除操作,但这些不是标准的。对于转换,考虑使用 jq(命令行)或编写应用代码。要查看和探索 JSON 结构,我们的 JSON 格式化工具 帮助你在编写查询前理解数据。

相关资源

Published on 2025-07-04
JSONPath Query Guide: Extracting Data Like a Pro | alltools.one