JSON 与 YAML 互转

JSON 与 YAML 双向互转:转 YAML 输出 2 空格缩进配置,转 JSON 输出格式化结果。

K8s 的 Deployment、CI 的 workflow 都用 YAML 写,而接口和程序配置往往给的是 JSON,两边对照着改容易漏缩进,也可能把字符串写成数字。这里做的是双向转换:JSON 转 YAML 得到缩进规范、可直接提交的配置,YAML 转 JSON 得到标准格式化的 JSON 便于程序读取。

转换基于 js-yaml,在浏览器里完成,配置文件内容不会离开本机,含密钥的清单也能安全处理。需要留意的是 YAML 的标量类型靠推断,不加引号的 007、010 这类值会被当成数字而丢掉前导零,注释和锚点在转换中也无法保留,下面会说明哪些信息会在转换时丢失以及怎么规避。

双向转换的行为

JSON 转 YAML 用 js-yaml 序列化,缩进固定 2 个空格,不做行宽折行,键的顺序按 JSON 中的顺序保留。YAML 转 JSON 会先把文档加载成对象,再以 2 空格缩进输出标准 JSON。YAML 的注释在转成 JSON 时会全部丢失,锚点与别名会被展开成完整内容,因为 JSON 语法里没有对应结构。YAML 的多文档写法会直接报错,提示一个流里只能有一个文档,需要拆成单个文档分别转换。

标量类型的歧义

YAML 里不加引号的值会被类型推断,转成 JSON 后类型可能和预期不同。实测带前导零的 010 和 007 会被解析成数字 10 和 7,前导零直接丢失;小数 3.141592653589793238 会被截断到双精度;超过 15 位有效数字的大整数同样变成近似值。想保持字符串原样就必须加引号,写成带引号的 007 在转换后会保留为字符串,输出时也会自动补回引号。布尔和 null 同理,不加引号会变成 JSON 的 true 和 null,加了引号就是字符串。

数值格式与键顺序

JSON 转 YAML 这一侧也有格式变化:JSON 里的 1.0 经解析后就是整数 1,输出成 YAML 也是 1;科学计数法写的 1e3 会被写成 1000,写法无法保留,因为数字在解析阶段就已归一化。纯数字键名会被 JavaScript 对象按升序重排到最前面,非数字键保持插入顺序,做配置对比时要注意这一点。JSON 本身不支持注释,所以转出的 YAML 不会带注释,需要说明文字只能手工补上井号开头的行。

广告

常见问题

转换后 YAML 里的注释和锚点会保留吗?
都不会。JSON 语法不支持注释,所以 YAML 转 JSON 时注释直接丢弃,反向转换也不可能凭空生成注释,需要注释就在转换后手工补。锚点与别名会被展开成重复的完整内容,引用关系无法在 JSON 里表达,文件体积会因此变大。
为什么数字字段转换后前导零没了、精度也变了?
因为 YAML 会把不加引号的值按类型解析,010 变成数字 10,位数较多的小数受双精度浮点限制被截断,这发生在加载阶段而不是序列化阶段。要精确保留就把值写成带引号的字符串,或者把这类字段在程序里改成按字符串处理。
多个分隔符隔开的 YAML 文档能一次转换吗?
不能。转换器按单文档加载,遇到多个文档会抛出一个流里只能有一个文档的错误。需要先把每个文档拆出来单独转换,再在 JSON 侧合并成数组,或者分别处理后再按需组装。
生成的 YAML 缩进是多少,能直接用吗?
缩进固定为 2 个空格,这是序列化库的默认风格,也是 K8s、Ansible、GitHub Actions 等配置的通行写法,复制出来即可提交。页面不提供缩进宽度和行宽选项,如果项目要求 4 空格或需要强制折行,需要在生成后自行重排。

相关工具

广告