这个工具是 YAML 与 JSON 之间的双向桥梁。YAML 转 JSON 会把文本交给 js-yaml 的 load,再用两空格缩进执行 JSON.stringify。JSON 转 YAML 则执行 JSON.parse,再用 js-yaml 的 dump,同样使用两空格缩进。所有处理都在浏览器标签页内完成,页面加载后不需要网络请求。语法错误会附带行号报告,因此 “at line 4” 这样的信息能直接指向出错的缩进或字符。面板还提供复制和下载,方便你把结果保存为文件。
YAML 标量是无类型的文本,解析器事后决定每个标量是字符串、数字、布尔值、null 还是时间戳。这个猜测正是大多数转换错误的起点,因为同样的字符在不同解析器中可能解析成不同的类型。
| 你写的 | 在此解析为 | 意外之处 |
|---|---|---|
version: 1.10 | 数字 1.1 | 末尾的零丢失 |
zip: 01234 | 数字 1234 | 前导零丢失 |
country: NO | 字符串 "NO" | YAML 1.1 解析器会读成 false(挪威问题) |
enabled: yes | 字符串 "yes" | YAML 1.1 解析器会读成 true |
flag: True | 布尔值 true | true 和 false 不区分大小写 |
count: 1e3 | 数字 1000 | 科学计数法会被当作数字 |
id: 12345678901234567890 | 舍入后的数字 | 超过 2^53 后精度丢失 |
big: .inf | Infinity,随后 null | JSON 无法表达 |
教训不是说 YAML 坏了,而是未加引号的标量带有含义。挪威问题是最典型的例子:写作 NO 的国家代码对 YAML 1.2 解析器是字符串,对 YAML 1.1 解析器却是布尔值 false。当两个系统对 schema 的理解不一致时,数据会在无声中改变含义。
考虑这个输入:
service: checkout
version: 1.10
retries: 3
enabled: yes
region: NO
JSON 输出为:
{
"service": "checkout",
"version": 1.1,
"retries": 3,
"enabled": "yes",
"region": "NO"
}
有两件事在无声中出了错。版本号丢了末尾的零,而 enabled 和 region 是字符串,任何读文件的人都会以为它们是布尔值和国别代码。修正后的 YAML 给有歧义的值加上引号:
service: checkout
version: "1.10"
retries: 3
enabled: "yes"
region: "NO"
这样就没有任何解析器能重新解释它们了。
加引号是主要手段。双引号最通用;单引号也可以,而且 YAML dumper 在需要保护字符串时正是输出单引号。你还可以用 version: !!str 1.10 这样的标签明确指定类型。把 JSON 转回 YAML 时,dumper 会替你完成这项工作:JSON 字符串 "yes" 会被写成 'yes',字符串 "1.10" 写成 '1.10',正是为了重新读取 YAML 时不会把它们变成布尔值或数字。这就是为什么 JSON 到 YAML 再回到 JSON 的往返能正确保留字符串值。
--- 分隔符会产生错误;请分段转换。两种格式重叠很多,因此选择通常取决于谁来编辑文件以及消费方有多严格。YAML 手写起来很舒服:支持注释、省略大部分括号和花括号,还能用块标量处理多行字符串。代价是对缩进敏感,以及上面描述的类型猜测。JSON 无歧义,几乎每种语言和 API 都支持,但它没有注释、要求键加引号,并且拒绝尾随逗号。
| 情况 | 更好的选择 |
|---|---|
| 带注释、手工编辑的配置 | YAML,并给有歧义的字符串加引号 |
| API 请求或响应体 | JSON |
| 跨语言边界的数据 | JSON,因为它的类型是固定的 |
| 被 YAML 1.1 工具消费的配置 | YAML,但给任何可能成为布尔值的项加引号 |
| 必须保留前导零或末尾小数的值 | 两者皆可,但要给值加引号 |
一条实用规则:人类编写和审阅的地方用 YAML,机器交换的地方用 JSON,并给任何可能被解析器误认为数字或布尔值的字符串加引号。
YAML (YAML Ain't Markup Language) 是一种人类可读的数据序列化格式,常用于配置文件和数据交换。它使用缩进表示结构,便于人类读写,同时可由机器解析。
YAML 更人类可读且支持注释,非常适合配置文件。JSON 在编程语言中支持更广泛,是 API 响应的标准格式。YAML 用缩进表示结构,JSON 用花括号和方括号。两种格式可以表示相同的数据结构。
可以,该工具完全支持复杂的嵌套对象、数组和多级结构。无论是深度嵌套的配置文件还是复杂的数据层级,转换器在 YAML 和 JSON 格式之间转换时都能保留完整结构。
YAML 没有明确的数字类型,解析器只能猜测。标量 1.10 看起来像浮点数,解析成 JavaScript 数字后末尾的零没有意义,因此 1.10 和 1.1 是同一个值,JSON 输出就会打印 1.1。如果版本号必须原样保留为文本,请在源文件中加引号:version: "1.10"。引号会告诉解析器把字符当作字符串,数值就能完整往返。
在这里不会。本转换器使用 js-yaml 的默认核心 schema,其中只有 true 和 false(不分大小写)是布尔值,因此 NO 会被读写成字符串 "NO"。著名的挪威问题属于 YAML 1.1 解析器(例如某些版本的 PyYAML),它们会把未加引号的 NO、yes、on、off 当作布尔值。由于同一份文件在不同工具里可能有不同含义,稳妥的做法是给任何可能被误认为布尔值的字符串加上引号。
JSON 没有注释语法,因此注释无法在 JSON 输出中表示,在加载 YAML 时就被丢弃了。如果保留注释很重要,请保留原始 YAML 文件,把 JSON 当作派生产物。从 JSON 转回 YAML 也不会恢复它们,因为这些信息从未存入解析后的数据里。
由 HandyTools Hub 团队审校 · 最后更新