数据与表格

YAML 与 JSON 互转

把 Kubernetes、Docker Compose、GitHub Actions 的 YAML 配置转成 JSON 检查,或者把 JSON 转成 YAML 写进配置文件。转换时,工具会逐条指出那些「换一个解析器意思就变了」的写法,比如国家代码 no 被读成 false、文件权限 0755 被读成 493。

全部在你的浏览器里运行,这里输入的内容不会上传。

怎么用

  1. 选择转换方向。YAML → JSON 时可以选按 YAML 1.2 还是 1.1 解析:1.2 是现行规范,Python 的 PyYAML、一些老工具按 1.1 解析。
  2. 把内容粘贴到左侧,右侧实时给出结果。出错时会显示出错的行号和列号。
  3. 看结果下方的黄色提示:每一条都指出一个在不同 YAML 版本里含义不同、或者被悄悄改了写法的值,以及它在第几行。
  4. 点「把结果作为输入反向转换」可以来回转一遍,检查转换前后是否一致。

YAML 最容易出错的地方

YAML 1.1 和 1.2 的差别

YAML 有两个广泛使用的版本。YAML 1.2 于 2009 年发布,主要目标是成为 JSON 的严格超集,同时去掉了许多容易出问题的隐式类型规则。按 1.2 的核心规则,不加引号时只有 true、false(及其大小写变体)是布尔值;而 YAML 1.1 的布尔类型还包括 yes、no、on、off、y、n 等写法。PyYAML 明确说明它实现的是 YAML 1.1。所以同一行 COUNTRY: no,按 1.2 读是字符串 no,按 1.1 读是 false。挪威的国家代码正好是 NO,这个坑因此被称为「挪威问题」。

数字:0755、22:22、1.10

YAML 1.1 的整数规则里,以 0 开头的数字是八进制,用冒号连接的数字是六十进制(本意是写时间和角度)。所以 mode: 0755 按 1.1 读是 493,按 1.2 读是十进制的 755,两者都不是你想要的「0755」这串文字;Docker Compose 里不加引号的端口映射 22:22,按 1.1 读成了 22 × 60 + 22 = 1342。另一个两个版本都有的坑:版本号 1.10 会被当成小数,变成 1.1。

本工具按 1.2 解析时会逐个检查不加引号的值,遇到上面这几种情况就在结果下方提示,并写明行号。最稳妥的做法是:凡是想当文字的值,都加上引号。

JSON 转 YAML 时自动加引号

把 JSON 转成 YAML 时,工具按 1.1 的规则判断哪些字符串需要引号,所以 "no"、"on"、"0755"、"22:22"、"1.10" 都会带上引号,连键名 n 也会(1.1 里 n 表示 false)。这样写出来的 YAML,不管用 1.1 还是 1.2 的解析器读回来,结果都和原来的 JSON 一致。多行字符串会写成 | 块样式,便于阅读。

精度与安全

整数一律按任意精度读取,12345678901234567890 这样超过 2^53 的整数不会被改成 12345678901234567000。锚点和别名(&base、*base)会被展开;为了防止「十亿笑声」这类用大量嵌套别名撑爆内存的输入,展开的别名数量有上限。重复的键会报错,而不是默默保留其中一个。

示例

YAML按 1.2 读按 1.1 读
country: no"no"(字符串)false
on: 1键名是 "on"键名变成 "true"
mode: 0755755493
port: 22:22"22:22"(字符串)1342
version: 1.101.11.1
country: "no""no""no"

反过来,JSON {"country": "no", "mode": "0755", "v": "1.10"} 转成 YAML 是 country: "no"、mode: "0755"、v: "1.10",三个值都带引号,任何解析器都会读回字符串。

局限

  • YAML 里的注释在转成 JSON 时会丢失,JSON 没有注释。
  • JSON 转 YAML 时键的顺序保持不变,但原来 YAML 里的注释、锚点、引号风格无法还原。
  • 按 YAML 1.1 解析时,日期形式的值会被读成时间戳并输出为 ISO 8601 字符串;按 1.2 解析时保持原文。
  • 自定义标签(例如 AWS CloudFormation 模板里的 !Ref、!Sub)会被丢掉,只留下后面的值:!Ref MyBucket 转成 JSON 是 "MyBucket"。转换这类模板请用它们自己的工具。

常见问题

为什么 no 变成了 false?

按 YAML 1.1 的规则,yes、no、on、off 都是布尔值。PyYAML 等按 1.1 解析的工具就会这样读。要表示文字,请加引号:"no"。

文件权限 0755 为什么变了?

YAML 1.1 把 0 开头的数字当八进制,0755 是 493;YAML 1.2 当十进制,是 755。请写成 "0755" 或 0o755。

Docker Compose 的端口为什么要加引号?

不加引号的 22:22 在 YAML 1.1 里是六十进制数 1342。写成 "22:22" 才能确保被当作文字。

YAML 注释能保留到 JSON 吗?

不能,JSON 格式本身不支持注释。

我的配置会上传吗?

不会。解析和转换都在你的浏览器里完成。

参考资料

↵ 打开 · Esc 关闭