← 返回博客

JSON 路径查询:导航复杂的 JSON 结构

掌握 JSON 路径导航和查询。学习使用 JSONPath、jq 和路径查找工具从嵌套 JSON 中提取数据。

Big JSON Team12 分钟阅读tools
B

Big JSON Team

Technical Writer

Expert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.

12 分钟阅读

# JSON 路径查询:导航复杂的 JSON 结构

JSON 路径是用于 JSON 的查询语言,类似于 XML 的 XPath。它允许您导航和从复杂的 JSON 结构中提取特定数据。

什么是 JSON 路径?

JSON 路径提供了一种标准化的方式来定位 JSON 文档中的特定数据。它在调试、数据提取和自动化中非常有用。

JSONPath 的优势

  • 精确选择: 定位嵌套的特定值
  • 查询过滤: 按条件选择数据
  • 递归搜索: 在任何深度找到匹配项
  • 转换数据: 在提取过程中修改数据
  • 跨平台: 在许多编程语言中支持

JSONPath 语法

基本运算符

| 运算符 | 说明 | 例子 |

|--------|-----|------|

| $ | 根对象 | $ |

| . | 点符号(子对象) | $.store |

| [] | 方括号符号 | $['store'] |

| [n] | 数组索引 | $.books[0] |

| [] | 通配符(所有子项) | $.books[] |

| .. | 递归搜索 | $..price |

| [?()] | 过滤表达式 | $.books[?(@.price < 10)] |

| [start:end] | 数组切片 | $.books[0:2] |

示例 JSON

{

"书店": {

"书籍": [

{

"标题": "活着",

"作者": "余华",

"价格": 25.00,

"年份": 2018

},

{

"标题": "呐喊",

"作者": "鲁迅",

"价格": 20.00,

"年份": 2015

},

{

"标题": "边城",

"作者": "沈从文",

"价格": 18.00,

"年份": 2017

}

],

"地址": "北京市东城区"

},

"在线购买": {

"网站": "bookstore.com",

"配送": "全国"

}

}

路径示例

| 路径 | 说明 | 结果 |

|------|-----|------|

| $.书店.书籍[0].标题 | 第一本书的标题 | "活着" |

| $.书店.书籍[].价格 | 所有书的价格 | [25.00, 20.00, 18.00] |

| $.书店.书籍[?(@.价格 < 20)] | 价格低于 20 的书 | 边城 |

| $..作者 | 所有作者(任何深度) | ["余华", "鲁迅", "沈从文"] |

| $.书店.书籍[0:2] | 前两本书 | 活着、呐喊 |

过滤和选择

比较运算符

$.books[?(@.price > 20)]        # 价格 > 20

$.books[?(@.price <= 20)] # 价格 <= 20

$.books[?(@.year == 2018)] # 年份等于 2018

$.books[?(@.author != "鲁迅")] # 作者不是鲁迅

逻辑运算符

$.books[?(@.price > 20 && @.year > 2015)]    # 价格 > 20 且年份 > 2015

$.books[?(@.price < 20 || @.year == 2018)] # 价格 < 20 或年份为 2018

字符串匹配

$.books[?(@.title =~ /活/)]     # 标题包含"活"

$.books[?(@.author.length > 2)] # 作者名字长度 > 2

递归搜索

找到所有特定字段

$..价格          # 找到所有价格字段

$..作者 # 找到所有作者

$..标题 # 找到所有标题

示例

对于上面的 JSON:

$..作者   # 返回: ["余华", "鲁迅", "沈从文"]

$..价格 # 返回: [25.00, 20.00, 18.00]

数组操作

索引和切片

$.books[0]       # 第一本书

$.books[-1] # 最后一本书

$.books[0:2] # 第一和第二本书

$.books[1:] # 从第二本开始的所有书

$.books[-2:] # 最后两本书

使用通配符

$.books[].title          # 所有书的标题

$.books[].price # 所有书的价格

$..books[].author # 任何深度的所有作者

使用 Big JSON Viewer

Big JSON Viewer 有内置的路径查找器。

使用步骤:
  • 访问 bigjson.online
  • 上传或粘贴 JSON
  • 点击任何值或字段
  • 路径自动显示在顶部
  • 点击复制按钮复制路径
  • 特点:
    • ✅ 自动生成路径
    • ✅ 一键复制
    • ✅ 处理超大文件
    • ✅ 可视化树导航
    • ✅ 搜索功能

    jq 命令行工具

    jq 是命令行 JSON 处理器,支持强大的路径查询。

    安装

    # macOS
    

    brew install jq

    # Ubuntu/Debian

    sudo apt-get install jq

    # Windows (Scoop)

    scoop install jq

    基本路径查询

    # 单个字段
    

    jq '.书店.书籍[0].标题' data.json

    # 输出:"活着"

    # 所有元素

    jq '.书店.书籍[].标题' data.json

    # 输出:

    # "活着"

    # "呐喊"

    # "边城"

    # 所有价格

    jq '.书店.书籍[].价格' data.json

    # 递归搜索

    jq '.. | .作者? | select(. != null)' data.json

    过滤

    # 选择价格 < 20 的书
    

    jq '.书店.书籍[] | select(.价格 < 20)' data.json

    # 提取标题和价格

    jq '.书店.书籍[] | {title: .标题, price: .价格}' data.json

    # 过滤并排序

    jq '.书店.书籍 | sort_by(.价格)' data.json

    转换数据

    # 收集所有标题
    

    jq '.书店.书籍[].标题' data.json | jq -s .

    # 创建新的 JSON 结构

    jq '.书店.书籍 | map({title: .标题, author: .作者})' data.json

    # 计数

    jq '.书店.书籍 | length' data.json

    高级查询

    # 按条件分组
    

    jq 'group_by(.年份)' data.json

    # 获取第一个匹配项

    jq '.书店.书籍 | map(select(.作者 == "鲁迅")) | .[0]' data.json

    # 计算统计

    jq '.书店.书籍 | {

    平均价格: (map(.价格) | add / length),

    总数: length,

    最贵: max_by(.价格).标题

    }' data.json

    JavaScript JSONPath 库

    quicktype JSONPath

    npm install jsonpath-plus
    使用:
    const { JSONPath } = require('jsonpath-plus');
    
    

    const data = {

    书店: {

    书籍: [

    { 标题: "活着", 价格: 25, 作者: "余华" },

    { 标题: "呐喊", 价格: 20, 作者: "鲁迅" },

    { 标题: "边城", 价格: 18, 作者: "沈从文" }

    ]

    }

    };

    // 基本路径

    const titles = JSONPath({

    path: '$.书店.书籍[].标题',

    json: data

    });

    console.log(titles); // ["活着", "呐喊", "边城"]

    // 过滤

    const cheapBooks = JSONPath({

    path: '$.书店.书籍[?(@.价格 < 20)]',

    json: data

    });

    console.log(cheapBooks); // 返回边城的数据

    // 递归搜索

    const allAuthors = JSONPath({

    path: '$..作者',

    json: data

    });

    console.log(allAuthors); // ["余华", "鲁迅", "沈从文"]

    Python JSONPath

    jsonpath-ng

    pip install jsonpath-ng
    使用:
    from jsonpath_ng import parse
    
    

    data = {

    "书店": {

    "书籍": [

    {"标题": "活着", "价格": 25, "作者": "余华"},

    {"标题": "呐喊", "价格": 20, "作者": "鲁迅"},

    {"标题": "边城", "价格": 18, "作者": "沈从文"}

    ]

    }

    }

    # 基本查询

    jsonpath_expr = parse('$.书店.书籍[].标题')

    titles = [match.value for match in jsonpath_expr.find(data)]

    print(titles) # ['活着', '呐喊', '边城']

    # 过滤查询

    jsonpath_expr = parse('$.书店.书籍[?(@.价格 < 20)]')

    cheap = [match.value for match in jsonpath_expr.find(data)]

    print(cheap)

    # 递归搜索

    jsonpath_expr = parse('$..作者')

    authors = [match.value for match in jsonpath_expr.find(data)]

    print(authors) # ['余华', '鲁迅', '沈从文']

    常见用例

    提取 API 响应数据

    # 从 API 获取并提取用户名
    

    curl https://api.example.com/users | jq '.data[].name'

    # 提取错误消息

    curl https://api.example.com/error | jq '.errors[0].message'

    数据验证

    # 检查是否所有价格都 > 0
    

    jq 'all(.书店.书籍[].价格 > 0)' data.json

    # 查找缺失字段

    jq '.书店.书籍[] | select(.作者 == null)' data.json

    数据转换

    # 转换为 CSV(与其他工具结合)
    

    jq -r '.书店.书籍[] | [.标题, .作者, .价格] | @csv' data.json

    # 转换为 SQL INSERT

    jq -r '.书店.书籍[] | "INSERT INTO books VALUES (\(.标题), \(.价格));"' data.json

    路径查找工具比较

    | 工具 | 易用性 | 功能 | 最佳用途 |

    |------|--------|------|---------|

    | Big JSON Viewer | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 可视化查找 |

    | jq | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 命令行强大 |

    | 在线工具 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | 快速查询 |

    | IDE(VS Code) | ⭐⭐⭐⭐ | ⭐⭐⭐ | 开发时 |

    | JavaScript 库 | ⭐⭐⭐ | ⭐⭐⭐⭐ | 应用内 |

    最佳实践

    1. 从简单开始

    先从基本路径开始,逐步添加过滤条件。

    # ✓ 简单开始
    

    jq '.书籍[0]'

    # ✓ 逐步添加

    jq '.书籍[0].标题'

    # ✓ 然后过滤

    jq '.书籍[] | select(.价格 < 20)'

    2. 测试小样本

    在大文件上运行之前测试小的 JSON 样本。

    3. 使用正确的工具

    • 可视化探索: Big JSON Viewer
    • 脚本化查询: jq 或 Python
    • 应用集成: JavaScript 库

    4. 保存常用查询

    创建脚本或别名以便重用:

    # ~/.bashrc 中的别名
    

    alias get-book-titles='jq ".书店.书籍[].标题" data.json'

    # 使用

    get-book-titles

    故障排除

    路径返回 null

    原因: 字段名或路径不匹配
    # 检查正确的字段名
    

    jq 'keys' data.json

    # 探索结构

    jq '.' data.json | less

    性能慢

    对于大文件,使用流式处理:

    # 对于 > 100MB 的文件
    

    jq '.书籍[] | select(.价格 < 20)' huge.json > results.json

    结论

    JSON 路径查询是处理复杂数据的基本技能。无论您是调试 API 响应、提取配置值还是转换数据,掌握路径语法都会大大提高您的生产力。

    快速参考

    | 任务 | 命令 |

    |------|------|

    | 获取第一个元素 | $.[0] |

    | 获取所有元素 | $.[*] |

    | 按值过滤 | $.[]|select(.价格 < 20) |

    | 递归搜索 | $..$ |

    | 数组切片 | $.[0:3] |

    现在您已准备好像专业人士一样查询 JSON!

    Share:

    相关文章

    Read in English