YAML

1 tools

数据序列化格式

数据序列化是将结构化数据转换为可存储或传输格式的过程,之后可以重新构建。

JSON、YAML、TOML 和 XML 是软件开发中四种主流的基于文本的序列化格式。

JSON 与 YAML 对比

JSON 和 YAML 表示相同的数据模型。YAML 是 JSON 的严格超集——任何有效的 JSON 文档也是有效的 YAML。

JSON
{
  "server": {
    "host": "localhost",
    "port": 8080,
    "debug": true
  },
  "database": {
    "url": "postgres://localhost/mydb",
    "pool": 10
  }
}
YAML
server:
  host: localhost
  port: 8080
  debug: true
database:
  url: postgres://localhost/mydb
  pool: 10

YAML 使用缩进代替括号,并省略大多数字符串值的引号,使其对于手动编辑的文件更紧凑、更易读。

格式比较

格式可读性注释数组最适合
JSON★★★☆☆不支持注释原生支持API、数据交换
YAML★★★★★支持(#)原生支持配置文件、IaC
TOML★★★★☆支持(#)原生支持应用配置(Rust、Python)
XML★★☆☆☆支持(<!-- -->)重复元素文档、SOAP、SVG

YAML 的陷阱

YAML 功能强大,但有一些众所周知的边缘情况会让开发者感到意外:

挪威问题

在 YAML 1.1 中,裸值 'NO' 被解释为布尔 false。国家代码 NO(挪威)、OFF、FALSE、N 都被解析为 false。请始终对歧义字符串加引号。

缩进敏感性

YAML 使用缩进来定义结构。多一个空格或一个制表符可能完全改变文档的含义。YAML 中禁止使用制表符——只能用空格。

隐式类型强制转换

看起来像数字、布尔值或 null 的值会被自动转换。对需要保留为字符串的值加引号。

禁止使用制表符

YAML 规范明确禁止使用制表符进行缩进。请将编辑器配置为在 YAML 文件中使用空格。

多行字符串模式

YAML 有两个多行字符串指示符:|(字面块,保留换行符)和 >(折叠块,将换行符转为空格)。

锚点/别名循环

YAML 锚点(&)和别名(*)允许节点重用,但可能创建循环引用,导致无限循环。

YAML 的独特功能

注释

YAML 使用 # 字符支持注释。这是相对于 JSON 在配置文件方面最大的实际优势之一。

锚点与别名

YAML 允许用 &锚点名称 定义节点,并在任何地方用 *锚点名称 重用。

多行字符串

YAML 支持两种模式的块标量:字面块(|)完全保留换行符;折叠块(>)将换行符转换为空格。

何时需要转换

CI/CD 流水线配置

GitHub Actions、GitLab CI 和 CircleCI 原生使用 YAML。以编程方式生成流水线配置时,通常更容易先构建 JSON 对象再转换为 YAML。

Kubernetes 清单

Kubernetes 资源以 YAML 定义,但部分工具输出 JSON。在格式间转换可检查 API 响应。

处理 API 响应

REST API 返回 JSON。将这些数据输入基于 YAML 的配置系统(如 Ansible、Kubernetes)时,转换器弥合了差距。

配置迁移

从一个工具迁移到另一个工具通常意味着转换其配置格式。

Schema 验证工作流

JSON Schema 工具更成熟。常见模式:以 YAML 编写配置提高可读性,转换为 JSON 进行验证,再转回进行部署。

与 API 数据交换

内部工具可能使用 YAML 配置,而外部 API 需要 JSON。流水线中的转换器使两者保持同步。

常见问题

YAML 是 JSON 的超集吗?

是的。YAML 1.2 是 JSON 的严格超集——任何有效的 JSON 文档也是有效的 YAML。

为什么配置文件选择 YAML 而非 JSON?

YAML 支持注释,而 JSON 不支持。YAML 对深度嵌套结构也更紧凑。

什么是 TOML,什么时候使用?

TOML 专为配置文件设计,语法清晰、类型明确,类似 INI。是 Rust(Cargo.toml)和 Python(pyproject.toml)的标准。

JSON 转 YAML 会丢失信息吗?

很少。JSON 在大多数解析器中保留键顺序。YAML 支持 JSON 中没有等价物的锚点和标签。

JSON 输出中出现 'undefined' 是什么原因?

JSON.stringify 将数组中的 undefined 值转换为 null,并从对象中省略它们。

可以在 YAML 文件中使用 JSON 吗?

可以。由于 YAML 是 JSON 的超集,可以在 YAML 文档中直接嵌入 JSON 语法。