在 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 处理中遇到的坑 😊

相关推荐
Lovely Ruby2 分钟前
前端er Go-Frame 的学习笔记:实现 to-do 功能(一)
前端·学习·golang
稚辉君.MCA_P8_Java4 分钟前
Gemini永久会员 Java 返回最长有效子串长度
java·数据结构·后端·算法
我超级能吃的12 分钟前
线程池核心原理及使用
java·开发语言
路边草随风17 分钟前
java 实现 flink 读 kafka 写 delta
java·大数据·flink·kafka
逆风局?17 分钟前
后端Web实战(部门管理)——日志技术
java·前端
小马爱打代码21 分钟前
Spring AI:ChatClient实现对话效果
java·人工智能·spring
无敌最俊朗@26 分钟前
C++ 内存管理与编译原理 (面试复习2)
java·开发语言·jvm
赴前尘30 分钟前
docker 配置ipv6地址
java·docker·容器
开开心心就好32 分钟前
图片批量压缩工具:支持有损无损两种模式
java·游戏·pdf·excel·散列表·启发式算法·1024程序员节
Overt0p33 分钟前
博客系统(2)
java