FormatArc YAML 转 JSON 转换器的转换结果界面FormatArc YAML 转 JSON 转换器的转换结果界面
作者: FormatArc 编辑部发布日期: 2026-09-02更新日期: 2026-09-02

YAML 转 JSON 指南 — 避免 8 个转换陷阱(Python / yq / 在线工具)

快速选择:10 秒找到你的方法

  • 马上要转、不想装东西FormatArc YAML 转 JSON(浏览器内完成,无需上传,报错带行号)
  • 命令行 / 一行脚本yq -o=json '.' file.yaml(DevOps 圈的默认选择)
  • Python 脚本或数据管道python3 -c 'import sys, yaml, json; json.dump(yaml.safe_load(sys.stdin), sys.stdout, indent=2)' < file.yaml
  • Node.js 项目js-yamlyaml.load + JSON.stringify
  • Go 服务gopkg.in/yaml.v3 + encoding/json
  • Kubernetes 来回转换kubectl get ... -o json | yq -P '.'(转回 YAML)
  • 多文档 YAML(--- 分隔)yq -o=json '.' file.yaml(yq 默认按文档拆分)或输出 NDJSON
方法安装多文档锚点注释流式
FormatArc 浏览器无需仅第一篇展开丢失(JSON 不支持)不支持
yq -o=jsonbrew install yq全部(拆分或数组)展开丢失支持
Python yaml.safe_load + json.dumppip install pyyaml第一篇(safe_load)/ 全部(safe_load_all展开丢失手写循环
Node js-yaml yaml.loadnpm install js-yaml第一篇(load)/ 全部(loadAll展开丢失手写
Go yaml.Unmarshalgo get gopkg.in/yaml.v3第一篇 / 全部(Decoder 循环)展开丢失支持

YAML 转 JSON 的代码本身往往就一行。真正麻烦的是 8 个陷阱(Norway 问题、注释丢失、多文档处理、yaml.load 的安全隐患、整数键变字符串、锚点展开、1.0 变浮点数、类型推断随 schema 而异)。下面逐一展开,每个都配 before/after 示例。

为什么要把 YAML 转成 JSON

实际工作中经常遇到的场景:

  • Kubernetes API 提交:YAML 清单没法直接 POST 给 Kubernetes API,API 只接受 JSON 编码的请求体。
  • 调试 YAML 结构:YAML 靠缩进表达嵌套,层级一深就容易看错。转成 JSON 后结构一目了然,少个 - 或缩进错位立刻就能发现。
  • 对接只认 JSON 的工具:下游的 JSON 解析器、存 JSON 字段的数据库、带 JSON Schema 校验的事件总线——它们不接受 YAML。
  • 配置审计与安全扫描:把仓库里的 YAML 配置转成 JSON,做 diff 分析、Schema 校验或喂给安全扫描器。
  • 给 LLM 传上下文:把配置以 JSON 格式交给 LLM 时,模型对对象边界的识别比 YAML 缩进更稳定,嵌套结构尤其明显。LLM 输入用 Markdown 还是 HTML 中对比了不同格式的实测效果。

两种格式的底层差异决定了转换时的行为差异,理解这些差异才能避免踩坑。详见 YAML 和 JSON 的区别

方法 1:FormatArc 浏览器工具(无需上传)

不想装任何东西、马上要转换的话,YAML 转 JSON 是最快的。所有运算在浏览器内完成,数据不会发送到任何服务器。

  1. 打开该页面
  2. 把 YAML 粘贴到左侧编辑器
  3. 点「转换」按钮,右侧立即显示 JSON 结果

FormatArc YAML 转 JSON 转换结果FormatArc YAML 转 JSON 转换结果

转换的同时工具会校验 YAML 语法。缩进错误、缺少冒号、该用空格的地方用了 Tab——这些语法错误都会带行号报出来,所以即使你只是调试 YAML 而不需要转换,它也能当语法检查器用。

浏览器内处理在处理敏感数据时特别安全。Kubernetes Secret(虽然经过 base64 编码,但内容仍然是机密的)、Ansible vault 里的云厂商凭据、带 API token 的 CI 配置——粘贴进去的数据只存在于当前标签页,不会外泄。

这不是理论上的担忧。2025 年 11 月,安全公司 watchTowr 发现,知名在线格式化工具 JSONFormatter 和 CodeBeautify 的「保存」功能存在漏洞,导致 5GB 以上的用户输入数据(含凭据、私钥、API token)处于公开可访问状态(watchTowr 调查报告在新标签页中打开)。浏览器内完成全部运算的工具不存储也不发送输入,从根源上不存在泄露面。在线工具安全检测 介绍了粘贴敏感数据前的 5 项验证方法。

浏览器工具能正确处理的 YAML 特性包括:多行字符串(块标量 | 和折叠标量 >)、锚点与别名(内联展开)、任意深度的嵌套对象、混合类型数组、null / 布尔 / 数值类型。

方法 2:yq(DevOps 的默认选择)

yq 可以理解为 YAML 版的 jq——一个轻量级的命令行处理器。DevOps 管道里做 YAML 转 JSON,它的使用率最高。

# 基本转换
yq -o=json '.' input.yaml

# 从标准输入管道读入
cat config.yaml | yq -o=json '.'

# 保存到文件
yq -o=json '.' config.yaml > config.json

# 紧凑输出(单行)
yq -o=json -I=0 '.' config.yaml

# 只提取子树再转换
yq -o=json '.spec.template' deployment.yaml

# 边过滤边转换
yq -o=json '.items[] | select(.kind == "ConfigMap")' multi.yaml

安装方式:

# macOS
brew install yq

# Linux(snap)
snap install yq

# Linux(直接下载二进制)
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
sudo chmod +x /usr/local/bin/yq

# Go install
go install github.com/mikefarah/yq/v4@latest

注意:叫 yq 的工具有两个。本文用的是 Mike Farah 的 Go 版本,Kubernetes 和 CNCF 生态里广泛使用的那个。kislyuk 的 Python 版 yq 语法不同,两者都能用,但 2026 年 Go 版是事实标准。

用 yq 处理多文档 YAML

# 多文档 YAML(--- 分隔的多个文档)
yq -o=json '.' multi.yaml          # 每个输入文档输出一个 JSON
yq -o=json -I=0 '.' multi.yaml      # NDJSON 格式(每行一个文档)
yq eval-all '[.]' -o=json multi.yaml  # 所有文档包成一个 JSON 数组

把 Kubernetes 的「多资源清单」转成一个 JSON 数组时,eval-all '[.]' 是最干净的做法。

方法 3:Python(最灵活)

Python 标准库自带 json 模块,pyyaml 在大多数环境里也很容易装(pip install pyyaml)。

Python 一行命令

python3 -c 'import sys, yaml, json; json.dump(yaml.safe_load(sys.stdin), sys.stdout, indent=2)' < input.yaml > output.json

从标准输入读取 YAML,用 yaml.safe_load 解析,以 indent=2 的缩进输出格式化 JSON 到标准输出。

Python 脚本(多文档 + 错误处理)

import sys
import yaml
import json

with open("config.yaml") as f:
    data = yaml.safe_load(f)  # 多文档时用 safe_load_all()

with open("config.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=2, ensure_ascii=False)

这里必须用 yaml.safe_load。默认的 yaml.load 允许构建任意 Python 对象,恶意 YAML 文件可以借此执行远程代码(详见陷阱 4)。

Python + ruamel.yaml(尽量保留结构)

如果需要保留引号风格、键顺序等细节,可以用 ruamel.yaml(注意:JSON 标准本身不支持注释,所以 JSON 输出中注释仍然会丢失)。

from ruamel.yaml import YAML
import json
import sys

yaml_parser = YAML(typ="safe")
data = yaml_parser.load(open(sys.argv[1]))
json.dump(data, sys.stdout, indent=2, ensure_ascii=False)

大多数场景下 pyyaml.safe_load 够用。只有需要 YAML 格式精确往返保留时才考虑 ruamel.yaml

方法 4:Node.js(js-yaml)

Node.js 项目里 js-yaml 是标配。

const fs = require("fs");
const yaml = require("js-yaml");

// 单文档
const doc = yaml.load(fs.readFileSync("config.yaml", "utf8"));
fs.writeFileSync("config.json", JSON.stringify(doc, null, 2));

// 多文档
const docs = yaml.loadAll(fs.readFileSync("multi.yaml", "utf8"));
fs.writeFileSync("multi.json", JSON.stringify(docs, null, 2));

安装:npm install js-yamlyarn add js-yaml

处理不可信的 YAML 输入时,建议指定 yaml.load(text, { schema: yaml.JSON_SCHEMA }),限制为 JSON 兼容类型。默认的 DEFAULT_SCHEMA 包含 Norway 问题等 YAML 1.1 的遗留行为。

方法 5:Go(gopkg.in/yaml.v3)

package main

import (
    "encoding/json"
    "fmt"
    "os"

    "gopkg.in/yaml.v3"
)

func main() {
    data, _ := os.ReadFile("config.yaml")
    var obj interface{}
    yaml.Unmarshal(data, &obj)
    result, _ := json.MarshalIndent(obj, "", "  ")
    fmt.Println(string(result))
}

yaml.v3 由 go-yaml 团队维护,Kubernetes 内部也用它。注意:YAML 的整数键(123: foo)转 JSON 后会变成字符串键("123": "foo"),因为 JSON 对象键只允许字符串。

大文件多文档 YAML 需要流式处理时,用 yaml.NewDecoder 循环:

dec := yaml.NewDecoder(file)
for {
    var doc interface{}
    if err := dec.Decode(&doc); err != nil {
        if err == io.EOF { break }
        log.Fatal(err)
    }
    out, _ := json.Marshal(doc)
    fmt.Println(string(out))   // NDJSON:每行一个文档
}

内存占用恒定,不管文件多大都能处理。

转换时必知的 8 个陷阱

YAML 和 JSON 的数据模型不是一一对应的。实际工作中最常踩到以下 8 个问题。

陷阱 1:Norway 问题(NO 变成 false

YAML 1.1 规范把某些不带引号的字符串当作布尔值解析:

country: NO

转换结果:

{ "country": false }

NOnoOffOFFnNFalsefF 全部变成 false。反过来 YESYOnTrueTt 全部变成 true。在一份国家代码列表里写了 country: NO(挪威),结果被当成布尔值 false——这就是「Norway 问题」得名的由来。

解决办法:有歧义的字符串加引号。

country: "NO"

YAML 1.2(Core schema)已经移除了这个规则,但 PyYAML 的 safe_load 和很多工具仍然默认按 YAML 1.1 处理。两字母国家代码、1.0 这类版本字符串、用户输入的值——养成加引号的习惯最安全。

陷阱 2:注释会静默消失

YAML 支持 # 注释,JSON 不支持。YAML 里的注释在转换过程中会被完全丢弃:

# 生产环境数据库连接(禁止修改)
host: db.prod.internal
port: 5432  # PostgreSQL 默认端口

转换结果:

{ "host": "db.prod.internal", "port": 5432 }

不管用哪个转换工具,都无法把 YAML 注释保留到标准 JSON 里。如果注释内容很重要,要么用 ruamel.yaml 单独提取注释元数据,要么把 YAML 源文件作为唯一信息源保存。

陷阱 3:多文档 YAML — 默认只转第一篇

YAML 文件可以用 --- 分隔符包含多个文档:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
---
apiVersion: v1
kind: Service
metadata:
  name: app-service

默认行为:

  • yaml.safe_load(Python):静默返回第一篇,不给警告
  • yaml.load(js-yaml):同样只返回第一篇
  • yq -o=json '.':连续输出多个 JSON 文档(紧凑模式下是合法 NDJSON)

要获取所有文档组成 JSON 数组,需要显式指定:

yq eval-all '[.]' -o=json multi.yaml

Python:

import yaml, json
docs = list(yaml.safe_load_all(open("multi.yaml")))
json.dump(docs, open("multi.json", "w"), indent=2)

Node.js:

const docs = yaml.loadAll(fs.readFileSync("multi.yaml", "utf8"));
fs.writeFileSync("multi.json", JSON.stringify(docs, null, 2));

Kubernetes 的多资源清单文件几乎必然是多文档 YAML,一定要显式处理这种情况。

陷阱 4:yaml.load 有安全风险,必须用 safe_load

Python PyYAML 的默认 yaml.load 函数允许构建任意 Python 对象:

!!python/object/apply:os.system ["rm -rf /"]

恶意构造的 YAML 文件被 yaml.load 读取时可能执行系统命令。处理不可信输入时必须用 yaml.safe_load(多文档用 yaml.safe_load_all)。

Node.js 的 js-yaml 把默认安全函数命名为 yaml.load,危险函数叫 unsafeLoad。Python 和 Node 的命名是反的,跨语言项目里一定要确认。

yq 用的是 Go 的 yaml.v3,没有 Python !!python/object 对应的标签,所以天然安全。

陷阱 5:整数键变字符串

YAML 允许整数类型的键:

123: first
456: second

JSON 对象键只允许字符串,转换时自动强转:

{ "123": "first", "456": "second" }

大多数情况没问题,但如果下游代码用整数键查找(obj[123]),字符串键(obj["123"])就会匹配失败。需要在应用层做类型转换。

陷阱 6:锚点和别名会被内联展开

YAML 可以用 &anchor 定义值、*alias 引用:

defaults: &defaults
  timeout: 30
  retries: 3

production:
  <<: *defaults
  host: prod.internal

staging:
  <<: *defaults
  host: stage.internal

转 JSON 后锚点被内联展开,productionstaging 各自包含完整副本:

{
  "defaults": { "timeout": 30, "retries": 3 },
  "production": { "timeout": 30, "retries": 3, "host": "prod.internal" },
  "staging": { "timeout": 30, "retries": 3, "host": "stage.internal" }
}

数据本身是对的,但「共享默认值」的设计意图消失了。JSON 没有锚点概念,转回 YAML 也恢复不了原始结构。

陷阱 7:1.0 变浮点数(版本字符串被破坏)

YAML 把看起来像数字的值自动解析为数字:

version: 1.0
release: 2026

转换结果:

{ "version": 1.0, "release": 2026 }

你本来想要字符串 "1.0"(版本标签),结果被强制转成浮点数 1.0,不同 JSON 编码器可能输出 11.0if version == "1.0" 这类字符串比较就会失败。

解决办法:版本字符串加引号。

version: "1.0"
release: "2026"

同样的道理适用于:电话号码、邮编("01234" 前导零丢失)、看起来像十六进数的 commit hash("e10" 被误认为科学计数法 1e+10)等。

陷阱 8:类型推断行为随 schema 不同

YAML 规范定义了 3 种标准类型推断 schema:

  • FailSafe schema:只处理字符串、序列、映射。不解析数字和布尔值,最严格也最安全。
  • JSON schema:与 JSON 基础类型完全一致(字符串、数字、布尔、null、数组、对象)。不会出现 Norway 问题,yes/no 也不会被解析为布尔值。
  • Core schema(YAML 1.2 默认):在 JSON schema 基础上扩展,把 nullNullNULL~、空值都识别为 null,把 true/false/True/False/TRUE/FALSE 识别为布尔值。

大多数现代工具默认使用 Core schema。

Python 中强制使用 JSON schema:

yaml.safe_load(text, Loader=yaml.SafeLoader)  # 默认安全模式

Node.js js-yaml 中指定:

yaml.load(text, { schema: yaml.JSON_SCHEMA });

yq v4 默认使用 YAML 1.2 Core schema,不会出现 Norway 问题。

在线工具对比

2026 年主要在线 YAML 转 JSON 工具的特性对比:

工具浏览器内处理文件上传多文档行号报错无广告
FormatArc YAML 转 JSON支持无(仅粘贴)第一篇支持
onlineyamltools.com支持(声称)第一篇有限
jsonformatter.org支持(声称)第一篇不支持否(有广告)
codebeautify.org支持(声称)第一篇不支持否(有广告)
jsonlint.com支持第一篇支持
dadroit.com支持第一篇有限

处理敏感 YAML(Kubernetes Secret、Ansible vault、带 token 的 CI 配置)时,「浏览器内处理」是否属实很关键。打开开发者工具的 Network 面板切到离线模式,再执行转换——如果工具还能正常工作,说明确实没有外部通信。FormatArc 在断网状态下也能正常使用。

多文档 YAML 方面,上面列出的在线工具都只处理第一篇。需要多文档或 NDJSON 输出时,用 yq 或 Python。

YAML 转 JSON Lines(NDJSON)流式处理

输入是多文档 YAML、输出要对接流式消费端(Kafka producer、行级数据库加载器、日志收集器)时,JSON Lines(NDJSON)是合适的输出格式。

用 yq

# NDJSON:每个 YAML 文档输出一行 JSON
yq -o=json -I=0 '.' multi.yaml

# 过滤后输出 NDJSON
yq -o=json -I=0 '.items[]' kubernetes-list.yaml

用 Python 流式处理

import yaml
import json
import sys

for doc in yaml.safe_load_all(sys.stdin):
    sys.stdout.write(json.dumps(doc, ensure_ascii=False) + "\n")

运行方式:python3 yaml2ndjson.py < multi.yaml > multi.ndjson

不管输入文件多大,内存占用恒定(O(1)),几千篇文档的日志型 YAML 文件也能安全处理。

管道对接 Kafka / BigQuery / S3

# 流式加载到 BigQuery
yq -o=json -I=0 '.' events.yaml | bq load --source_format=NEWLINE_DELIMITED_JSON dataset.events -

# 流式上传到 S3
yq -o=json -I=0 '.' events.yaml | aws s3 cp - s3://bucket/events.ndjson

# 通过 kafkacat 发送到 Kafka
yq -o=json -I=0 '.' events.yaml | kafkacat -P -b broker:9092 -t events

CI/CD 自动化

主流 CI/CD 平台中 YAML 转 JSON 的配置示例。

GitHub Actions

name: Convert YAML config to JSON
on: [push, pull_request]

jobs:
  convert:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install yq
        run: |
          sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
          sudo chmod +x /usr/local/bin/yq
      - name: Convert
        run: yq -o=json '.' config.yaml > config.json
      - name: Validate against JSON Schema
        run: |
          npx ajv-cli validate -s schema.json -d config.json

Node.js 已就绪的流水线中,也可以直接用 formatarc npmnpx formatarc yaml-to-json config.yaml 在本地运行与 Web 版相同的转换引擎,无需安装额外二进制。

GitLab CI

convert-yaml:
  image: mikefarah/yq:latest
  stage: validate
  script:
    - yq -o=json '.' config.yaml > config.json
    - jq empty config.json   # 最终语法校验
  artifacts:
    paths:
      - config.json

Jenkins(Declarative Pipeline)

pipeline {
  agent any
  stages {
    stage('Convert YAML to JSON') {
      steps {
        sh 'yq -o=json . config.yaml > config.json'
        sh 'jq empty config.json'
      }
    }
  }
}

不管哪个平台,转换就是一条命令,直接嵌在管道中间就行,不会给流水线增加额外负担。

Kubernetes 实用工作流

实际运维中常见的模式:获取正在运行的 Deployment,编辑后在 YAML 和 JSON 之间来回转换。

# 以 JSON 格式获取当前 Deployment(kubectl 两种格式都支持)
kubectl get deployment web-app -o json > deployment.json

# 或者以 YAML 获取再转换(顺便验证本地 yq 可用)
kubectl get deployment web-app -o yaml | yq -o=json '.' > deployment.json

# 用 jq 修改内容(例:调整副本数)
jq '.spec.replicas = 5' deployment.json > updated.json

# 提交 Git 前转回 YAML
yq -P '.' updated.json > deployment.yaml

# 应用到集群
kubectl apply -f deployment.yaml

一条管道搞定:

kubectl get deployment web-app -o json \
  | jq '.spec.replicas = 5' \
  | yq -P '.' \
  > deployment.yaml

这个模式适用于 kubectl 的所有资源类型、Helm chart values 文件、自定义资源定义(CRD)。

常见问题

YAML 里写了 country: NO 为什么变成了 false

这就是「Norway 问题」。YAML 1.1 规范把 NOOffnFalse 等不带引号的字符串解析为布尔值 false。解决办法是加引号:country: "NO"。YAML 1.2 规范已移除这个行为,但很多工具仍默认 1.1。yq v4 使用 YAML 1.2 Core schema,不受此影响。

YAML 注释能保留到 JSON 输出里吗?

不能。标准 JSON 没有注释语法。变通方案包括:用 ruamel.yaml 把注释提取为独立元数据结构,或者使用非标准格式如 JSON5 / JSONC。如果注释很重要,把 YAML 作为信息源保留。JSON 内部的其他替代方案见 JSON 可以注释吗?

多文档 YAML 转换时怎么处理?

大多数工具默认只转换第一篇。要获取全部文档:Python 用 yaml.safe_load_all,Node.js 用 yaml.loadAll,或者 yq eval-all '[.]' 包成 JSON 数组。需要每行一个文档的流式输出时,用 yq -o=json -I=0

YAML 怎么输出为 NDJSON?

yq -o=json -I=0 '.' multi.yaml 输出紧凑的每行一个文档格式。Python 用 yaml.safe_load_all 逐篇读取再 json.dumps() 输出。NDJSON 是 BigQuery、S3、Kafka 等大数据管道的标准格式。

能把 YAML 转成 JSON5(带注释)吗?

JSON5 是允许注释的 JSON 超集。YAML 转 JSON5 需要先转成标准 JSON,再手动补回注释或用专用解析器。json5.org在新标签页中打开 的参考实现支持 JSON5 解析和输出,但主流 YAML 库没有直接输出 JSON5 的。

锚点和合并键在 JSON 中会保留吗?

不会。JSON 没有锚点或别名概念,转换时会被内联展开为完整数据副本。数据内容正确,但「共享默认值」的原始结构意图丢失了。

没有装 yq 或 Python,怎么把 YAML 转 JSON?

用 FormatArc YAML 转 JSON 工具,浏览器里直接粘贴转换,无需安装。另外几乎所有现代操作系统都自带 Python 3,pip install pyyaml 后终端里跑一行命令也能完成。

反向转换(JSON 转 YAML)

需要把 JSON 转回 YAML 时,可以用 FormatArc 的 JSON to YAML 工具,同样是浏览器内完成。各语言的脚本和 CLI 反向转换方法见 JSON 转 YAML 指南

总结

YAML 转 JSON 有 5 种方法覆盖所有场景:

  • 无需安装 + 敏感数据:FormatArc YAML 转 JSON — 浏览器内完成,行号报错
  • 命令行 / DevOps 管道yq -o=json '.' — 事实标准
  • Python 应用yaml.safe_load(禁用 yaml.load)+ json.dump
  • Node.js 应用js-yamlyaml.load,指定 JSON schema 更安全)
  • Go 服务gopkg.in/yaml.v3 + encoding/json,多文档用 Decoder 循环

8 个陷阱(Norway 问题 / 注释丢失 / 多文档处理 / yaml.load 安全风险 / 整数键变字符串 / 锚点展开 / 1.0 变浮点数 / schema 相关的类型推断)几乎每个人都会至少踩一次。记住三条原则就能避开大部分问题:有歧义的字符串加引号、用安全的解析函数、多文档显式处理。