当前位置:首页 > 文章列表 > Golang > Go教程 > Go GJSON 怎么一次读取多个不同路径的值

Go GJSON 怎么一次读取多个不同路径的值

来源:17golang原创 2026-10-13 15:59:34 0浏览 收藏

Go GJSON 需要读取多个不同路径时,最稳妥的做法是先用 gjson.Parse(或 ParseBytes)得到一个 Result,再通过 Result.Get 读取各个路径。这样同一份输入只建立一次解析结果;如果多个字段来自数组中的同类对象,再用 # 投影和多路径语法组合精简对象。

官方地址:https://github.com/tidwall/gjson

要点速览
  • 多个独立路径:解析一次,连续调用 root.Get(path)。
  • 同一数组的多个字段:用 items.#.field 或多路径对象收敛输出。
  • 缺失字段先看 Exists(),不要用空字符串代替业务判断。

解析一次,再读取多个独立路径

例如订单接口同时返回客户编号、订单金额和会员标记。直接对原字符串调用多次 gjson.Get 也能得到结果,但代码会把“输入文本”重复传入。把输入先交给 gjson.Parse,后续路径就集中在一个根结果上,便于统一处理缺失字段。

package main

import (
    "fmt"

    "github.com/tidwall/gjson"
)

func main() {
    payload := `{"customer":{"id":"C-17"},"order":{"total":128.5},"flags":{"vip":true}}`

    // 只解析一次,后面的 Get 都从同一个根结果继续查找。
    root := gjson.Parse(payload)
    customerID := root.Get("customer.id")
    total := root.Get("order.total")
    vip := root.Get("flags.vip")

    // 先判断存在性,再按 JSON 实际类型读取,避免空字符串掩盖缺失字段。
    fmt.Println(customerID.Exists(), customerID.String())
    fmt.Println(total.Exists(), total.Float())
    fmt.Println(vip.Exists(), vip.Bool())
}
Go GJSON 解析一次后通过 customer.id、order.total 和 flags.vip 三条路径读取不同 Result 的结构说明图
图1:Parse 一次后分发多个路径的结构说明图,不是运行截图或运行证据。

这里的“多个”是多个独立路径,不是一个叫作 GetMany 的标准 API。Result.Get 返回的仍是 gjson.Result:字符串使用 String(),数字使用 Int() 或 Float(),布尔值使用 Bool()。如果输入已经是字节切片,换成 gjson.ParseBytes(data) 即可。

数组字段用 # 做批量投影

当多个值来自数组中的同名字段,不必手写 items.0.id、items.1.id。路径中的 # 表示数组长度或遍历位置,items.#.id 会得到所有元素的 id,结果仍然是 JSON 数组。

package main

import (
    "fmt"

    "github.com/tidwall/gjson"
)

func main() {
    payload := `{"items":[{"id":101,"sku":"A-17","qty":2},{"id":102,"sku":"B-03","qty":1}]}`

    // # 遍历 items,并把每个对象的 id 投影成结果数组。
    ids := gjson.Get(payload, "items.#.id")
    for _, item := range ids.Array() {
        // 数字字段优先用 Int(),不要先转 String() 再解析。
        fmt.Println(item.Int())
    }

    // 同一输入还可以读取另一条独立路径,二者互不改变。
    quantities := gjson.Get(payload, "items.#.qty")
    fmt.Println(quantities.Raw)
}

如果要筛选数组中的多个匹配项,使用 #(条件)#;末尾第二个 # 很关键,因为没有它时通常只取第一个命中对象。筛选和投影是两个动作,先确定是否要“找哪些元素”,再决定要“留下哪些字段”。

同一对象的多个字段用多路径组装

如果调用方希望得到一个只包含指定字段的新对象数组,可以把字段映射写进多路径语法。例如 users.#.{"id":id,"name":name} 会遍历用户数组,并为每项创建只含 id 和 name 的对象。别名也可以不同,适合给下游接口生成稳定的展示结构。

package main

import (
    "fmt"

    "github.com/tidwall/gjson"
)

func main() {
    payload := `{"users":[{"id":7,"name":"Lin","role":"editor"},{"id":8,"name":"Qiao","role":"viewer"}]}`

    // 多路径只选择 id 和 name,role 等无关字段不会进入结果。
    compact := gjson.Get(payload, `users.#.{"id":id,"display_name":name}`)
    if compact.Type != gjson.JSON {
        // 类型不符合预期时及时停止向下游传递错误形态。
        panic("expected JSON array")
    }
    fmt.Println(compact.Raw)
}
GJSON 用 users.# 遍历数组并选择 id、name 形成精简对象数组的结构说明图
图2:数组投影与多路径对象组合的结构说明图,不是软件截图或执行结果。

筛选也能接在投影前面,例如 users.#(role=="editor")#. {"id":id}(实际路径中不要在点后插入空格)可以先收集所有编辑者,再只保留编号。实际项目中建议把这类路径集中成常量,避免散落在业务代码里难以修改。

缺失字段、空值与强类型转换

场景建议写法原因
判断字段是否存在result.Exists()区别于存在但值为空
保留 JSON 形态result.Raw适合直接转发数组或对象
读取整数result.Int()避免先转字符串
需要复杂校验解码到结构体GJSON 不替代领域校验

最后可以按这个边界选择方案:不同位置的少量字段,使用“解析一次 + 多次 Get”;数组同名字段,使用 #.字段;数组中每项要保留多个字段,使用多路径对象;如果后续需要必填校验、默认值和业务约束,再把精简后的 JSON 或完整输入交给结构体解码。

相关问题

多次调用 Result.Get 会重新解析整段 JSON 吗?

它会在根结果的原始 JSON 上继续查找,但代码层面复用了同一个解析结果。若路径数量很多,仍应把路径和取值逻辑集中管理,避免业务判断散落。

为什么读取不存在的路径后 String() 是空字符串?

空字符串可能来自缺失字段,也可能来自真实的空值。先调用 Exists(),必要时再检查 Type,不要只用 String() 的返回值判断。

多路径结果能直接当作 Go 结构体吗?

不能直接当作强类型结构体。多路径首先返回 gjson.Result 和 JSON 原文;需要强类型字段、必填规则或复杂校验时,仍要使用标准 JSON 解码或项目自己的转换层。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go GJSON 怎么读取键名包含点号的 JSON 字段Go GJSON 怎么读取键名包含点号的 JSON 字段
上一篇
Go GJSON 怎么读取键名包含点号的 JSON 字段
Go GJSON Exists 和空字符串判断有什么区别
下一篇
Go GJSON Exists 和空字符串判断有什么区别
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    460次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    521次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    539次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    488次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    307次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码