YAML 到 JSON 转换:会破坏配置文件的陷阱
Source: Dev.to
YAML 和 JSON 表示相同的数据结构——对象、数组、字符串、数字、布尔值和 null——因此转换本应直截了当。实际上,YAML 的特性和怪癖使得这个过程出乎意料地充满陷阱。
布尔强制转换
YAML 会自动将某些字符串解释为非字符串类型:
country: NO你期望:
{"country": "NO"}但实际得到:
{"country": false}YAML 将 "NO" 视为布尔值 false。同样,"YES" 会变成 true,"on" 会变成 true,"off" 会变成 false。这通常被称为 “挪威问题”。 要表示挪威的国家代码 (NO) 必须给它加引号:
country: "NO"数值和日期强制转换
其他令人惊讶的类型转换:
version: 1.0 # Becomes number 1, not string "1.0"
version: 1.10 # Becomes number 1.1, not string "1.10"
octal: 0777 # Becomes decimal 511 in YAML 1.1
date: 2024-01-15 # Becomes a Date object, not a stringversion: 1.10 的情况尤其危险:你期望得到字符串 "1.10",却得到数字 1.1。在版本比较中,1.1 与 1.10 差别很大。解决办法是对可能被误解的字符串加引号:
version: "1.10"Source: …
多行字符串
YAML 提供了几种多行字符串语法:
# 字面块(保留换行)
description: |
Line one
Line two
Line three
# 折叠块(用空格连接行)
description: >
This is all
one paragraph
on one line.
# 带有截断指示符
trailing_newline: |+
Keeps trailing newlines
no_trailing: |-
No trailing newlineJSON 没有多行字符串语法;所有换行必须使用 \n 转义。
字面块 (|) 转换为:
{"description": "Line one\nLine two\nLine three\n"}折叠块 (>) 转换为:
{"description": "This is all one paragraph on one line.\n"}尾随换行的行为(默认:单个尾随换行,+ 保留全部,- 去除)对精确字符串匹配很重要,必须正确处理。
注释
YAML 支持注释;JSON 不支持。
# This is a database configuration
database:
host: localhost # Change for production
port: 5432转换为 JSON 时会丢失所有注释:
{
"database": {
"host": "localhost",
"port": 5432
}
}这是一种单向的数据丢失。如果你将 YAML 转换为 JSON 再转换回 YAML,注释会消失——这对注释提供关键上下文的配置文件来说是个问题。
锚点和别名(引用)
YAML 允许通过锚点和别名复用映射:
defaults: &defaults
timeout: 30
retries: 3
production:
<<: *defaults
host: prod.example.com
staging:
<<: *defaults
host: staging.example.com&defaults定义锚点。*defaults引用它。<<合并引用的映射。
JSON 没有等价的机制,因此转换器必须将所有引用内联解析:
{
"defaults": {"timeout": 30, "retries": 3},
"production": {"timeout": 30, "retries": 3, "host": "prod.example.com"},
"staging": {"timeout": 30, "retries": 3, "host": "staging.example.com"}
}JSON 输出中数据被复制,导致文件体积增大,且失去了单一真相来源的好处。
排序
YAML 映射和 JSON 对象在规范上是无序的,但实际上 YAML 文件是按人类期望的顺序编写的。大多数转换器会保留插入顺序,但这并不能得到保证。
强大的转换器
我构建了一个 YAML‑到‑JSON 转换器,能够处理所有这些边缘情况:
- 布尔值强制转换警告
- 多行字符串转换
- 锚点解析
- 注释剥离(带有警告)
您可以在 zovo.one/free-tools/yaml-to-json-converter 试用它。它还支持 JSON‑到‑YAML 的反向转换。