在 YAML 中如何将 JSON 对象作为字符串整体赋值?——兼谈 Go Template 中的 fromJson 使用

在日常开发中,我们经常需要在配置文件(如 YAML)中嵌入一段 JSON 数据。有时,这段 JSON 并不是要被 YAML 解析器当作结构化对象处理,而是作为一个完整的字符串 传递给下游系统(比如 Go 模板、Helm Chart 或微服务配置)。那么,如何在 YAML 中正确地将一个 JSON 对象表示为字符串?本文将为你详细解答,并结合 Go Template 中的 fromJson 函数说明其典型应用场景。


一、问题背景

假设我们有如下 JSON 数据:

json 复制代码
{
  "name": "Alice",
  "age": 30,
  "hobbies": ["reading", "swimming"]
}

现在,我们需要将它作为一个字符串赋值给 YAML 文件中的某个字段,例如:

yaml 复制代码
data: ??? # 这里应该填什么?

注意:我们的目标是让 data 的值是一个字符串,而不是一个 YAML 映射(map)!


二、错误做法:直接写成 YAML 结构

很多初学者会这样写:

yaml 复制代码
# ❌ 错误!这会被解析为 map,不是字符串
data:
  name: Alice
  age: 30
  hobbies:
    - reading
    - swimming

这样写虽然语义上等价,但 data 是一个对象(map) ,而不是字符串。如果你后续要用 fromJson 去解析它,就会失败------因为它根本就不是 JSON 字符串!


三、正确做法:将 JSON 作为字符串嵌入 YAML

✅ 方法 1:使用单引号包裹(推荐)

yaml 复制代码
data: '{"name": "Alice", "age": 30, "hobbies": ["reading", "swimming"]}'
  • 单引号内的内容在 YAML 中不会转义,原样保留。
  • 简洁、安全、可读性好。
  • 是最常用的方式。

✅ 方法 2:使用双引号 + 转义(不推荐,但合法)

yaml 复制代码
data: "{\"name\": \"Alice\", \"age\": 30, \"hobbies\": [\"reading\", \"swimming\"]}"
  • 需要手动转义内部的双引号,容易出错。
  • 仅在特殊场景下使用。

✅ 方法 3:使用折叠块标量 >-(适合长 JSON)

yaml 复制代码
data: >-
  {"name": "Alice", "age": 30, "hobbies": ["reading", "swimming"]}
  • >- 表示"折叠换行并去除末尾换行",最终得到单行字符串。
  • 如果你为了可读性想分行写 JSON,需谨慎:YAML 会把换行转为空格,可能导致 JSON 格式错误。

🚫 不要使用 |(保留换行),因为会在字符串末尾添加 \n,破坏 JSON 合法性。


四、实际应用场景:Go Template 中的 fromJson

在 Helm、Kubernetes 或自定义 Go 应用中,我们常通过模板动态渲染配置。此时,fromJson 就派上用场了。

1. 定义 fromJson 函数

go 复制代码
func fromJSON(jsonStr string) interface{} {
    var result interface{}
    if err := json.Unmarshal([]byte(jsonStr), &result); err != nil {
        return map[string]interface{}{} // 安全兜底
    }
    return result
}

2. 注册到模板函数

go 复制代码
tmpl := template.Must(template.New("example").Funcs(template.FuncMap{
    "fromJson": fromJSON,
}).Parse(`...`))

3. 在模板中使用

假设 values.yaml 如下:

yaml 复制代码
userData: '{"name": "Alice", "age": 30, "hobbies": ["reading", "swimming"]}'

模板内容:

go 复制代码
{{- $user := fromJson .Values.userData }}
Name: {{ $user.name }}
Age: {{ $user.age }}
Hobbies: {{ join ", " $user.hobbies }}

输出结果:

复制代码
Name: Alice
Age: 30
Hobbies: reading, swimming

✅ 成功将 YAML 中的 JSON 字符串解析为结构化数据!


五、总结

场景 推荐写法
短 JSON 字符串 '{"key":"value"}'(单引号)
长 JSON(需换行) 谨慎使用 >-,确保无格式破坏
避免 直接写 YAML 结构(会被解析为 map)

记住:当你需要把 JSON 当作字符串传递时,必须用引号包裹,防止 YAML 解析器将其结构化。


六、延伸阅读


💡 小贴士 :在 Helm 中,官方已内置 fromJsontoJSON 函数,无需手动实现!

如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、转发!也欢迎在评论区交流你在 YAML/JSON 处理中遇到的坑 😊

相关推荐
一路向北North26 分钟前
Spring Security OAuth2.0(19):JWT令牌
java·后端·spring
玛卡巴卡ldf30 分钟前
【LeetCode 手撕算法】(细节知识点总结)
java·数据结构·算法·leetcode·力扣
一叶飘零_sweeeet1 小时前
IDEA 插件 Trae AI 最新全攻略(基于 TRAE AI: Coding Assistant 1.7.0.0)
java·intellij-idea·trae
KobeSacre1 小时前
CyclicBarrier 源码
java·jvm·算法
MacroZheng1 小时前
给Claude Code装上这款炫酷的HUD插件,状态信息就一目了然了!
java·人工智能·后端
我登哥MVP2 小时前
Hadoop成长史-从Nutch子项目到大数据生态王者
java·大数据·hadoop·分布式·云原生·云计算
进击切图仔2 小时前
SAM3 微调标注流水线和 Label Studio
java·服务器·前端
名字还没想好☜2 小时前
Go error 处理:errors.Is/As 与错误包装
开发语言·后端·golang·go·错误处理
java1234_小锋2 小时前
Maven 4 要来了:15 年后,Java 构建工具迎来“彻底重构“
java·重构·maven
霸道流氓气质2 小时前
Java 工程师 AI 智能体学习路线 · 阶段 1:AI / LLM 基础认知 详解
java·人工智能·学习