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

相关推荐
麻瓜生活睁不开眼4 小时前
Android16修改全局桌面视图边框四直角显示为弧边圆角
android·java·深度学习
dear_bi_MyOnly4 小时前
【MyBatis 操作数据库】
java·数据库·学习·mybatis·学习方法
Wang's Blog4 小时前
Go-Zero 项目开发43:基于 Filebeat 收集各个服务的日志信息
开发语言·golang·go-zero·filebeat
2601_953720824 小时前
【计算机毕业设计】基于Spring Boot的心理健康咨询与评测系统的设计与实现
java·spring boot·后端
丈剑走天涯5 小时前
JDK 17 正式特性
java·开发语言
圣光SG6 小时前
Java操作题练习(七)
java·开发语言·算法
@航空母舰7 小时前
SpringBoot通过Map实现天然的策略模式
java·spring boot·后端
Co_Hui8 小时前
Java 并发编程
java
long3169 小时前
Java 新手入门与实战开发指南
java·开发语言
执笔画流年呀9 小时前
Linux搭建Java项目部署环境
java·linux·运维