DevToolBox免费
博客

YAML 转 JSON 转换器完全指南:含代码示例

12 分钟阅读作者 DevToolBox

YAML 到 JSON 的转换是开发者日常面对的最常见数据格式任务之一。无论你管理 Kubernetes 清单、Docker Compose 文件、CI/CD 管道还是应用配置,都经常需要在 YAML 和 JSON 之间转换。YAML 以其可读性强、基于缩进的语法著称,而 JSON 则主导 API 和程序化数据交换。本综合指南涵盖了 YAML 到 JSON 转换器工具、解析过程、四种语言的代码示例、常见陷阱和最佳实践。如果你需要快速进行 YAML 到 JSON 的在线转换,请试用我们下方的免费工具。

立即试用我们的免费在线 YAML 到 JSON / JSON 到 YAML 转换工具。

什么是 YAML?

YAML(YAML Ain't Markup Language)是一种人类友好的数据序列化语言,广泛用于配置文件和数据交换。YAML 解析器读取基于缩进的结构,将其转换为字典、列表和标量等原生数据结构。

YAML 使用空白缩进(仅限空格,不允许制表符)来表示结构,使其视觉上整洁易读。它支持标量类型(字符串、整数、浮点数、布尔值、null)、序列(数组/列表)和映射(字典/对象)。高级功能包括锚点和别名用于数据重用、多行字符串的块标量(| 保持原样,> 折叠),以及用 --- 分隔的多文档文件。YAML 语法被设计为 JSON 的超集,即每个有效的 JSON 文档也是有效的 YAML。

YAML 是 Kubernetes 清单、Ansible playbook、Docker Compose 文件、GitHub Actions 工作流、Swagger/OpenAPI 规范、Spring Boot 配置等众多 DevOps 和云原生工具的首选格式。其相比 JSON 的可读性优势使其成为人类频繁编辑的文件的首选,而 JSON 仍是机器间通信和 API 的首选。

YAML 与 JSON:关键区别

了解 YAML 和 JSON 之间的区别有助于选择正确的格式并避免转换陷阱。以下是详细对比:

特性YAMLJSON
语法基于缩进,无需括号或大括号由括号和大括号分隔
注释支持 # 注释不支持注释
数据类型字符串、整数、浮点、布尔、null、日期、二进制字符串、数字、布尔、null、数组、对象
多行字符串块标量:|(保持原样)和 >(折叠)必须使用 \n 转义
锚点和别名支持 &* 数据重用不支持
可读性高度可读,标点符号少引号和括号较多
解析速度较慢(缩进敏感)较快(语法简单)

YAML 到 JSON 转换的工作原理

使用 YAML 到 JSON 转换器时,工具会执行多步解析和序列化过程。

第 1 步:词法分析(分词) — YAML 解析器逐字符扫描原始 YAML 文本,识别缩进级别、键值分隔符(:)、序列指示符(-)、块标量指示符(|>)、锚点(&)、别名(*)和标量值等标记。

第 2 步:解析(AST 构建) — 标记被组装成代表层次结构的抽象语法树(AST)。映射成为对象节点,序列成为数组节点,标量成为叶节点。

第 3 步:组合(原生数据结构) — AST 被转换为编程语言的原生数据结构。此时发生隐式类型转换:true/false/yes/no 变为布尔值,未引用的数字变为整数或浮点数。

第 4 步:JSON 序列化 — 原生数据结构被序列化为 JSON 文本。YAML 注释被丢弃,锚点和别名被完全展开。

YAML 到 JSON 代码示例

JavaScript / Node.js (js-yaml)

js-yaml 是最流行的 JavaScript YAML 解析器。使用 yaml.load() 解析 YAML,结合 JSON.stringify() 实现完整的 YAML 到 JSON 转换:

// ===== YAML to JSON (Node.js) =====
const yaml = require('js-yaml');
const fs = require('fs');

// Parse YAML string to JavaScript object
const yamlString = `
server:
  host: localhost
  port: 8080
  ssl: true
database:
  name: myapp
  replicas:
    - host: db1.example.com
      port: 5432
    - host: db2.example.com
      port: 5432
  # Connection pool settings
  pool:
    min: 5
    max: 20
`;

const data = yaml.load(yamlString);
const json = JSON.stringify(data, null, 2);
console.log(json);
// {
//   "server": {
//     "host": "localhost",
//     "port": 8080,
//     "ssl": true
//   },
//   "database": {
//     "name": "myapp",
//     "replicas": [
//       { "host": "db1.example.com", "port": 5432 },
//       { "host": "db2.example.com", "port": 5432 }
//     ],
//     "pool": { "min": 5, "max": 20 }
//   }
// }

// ===== JSON to YAML =====
const jsonData = { name: 'app', version: '2.0', features: ['auth', 'logging'] };
const yamlOutput = yaml.dump(jsonData, { indent: 2 });
console.log(yamlOutput);
// name: app
// version: '2.0'
// features:
//   - auth
//   - logging

// ===== Read YAML file and convert to JSON =====
const fileContent = fs.readFileSync('config.yaml', 'utf8');
const config = yaml.load(fileContent);
fs.writeFileSync('config.json', JSON.stringify(config, null, 2));

// ===== Handle multi-document YAML =====
const multiDoc = `
---
name: doc1
---
name: doc2
`;
const docs = yaml.loadAll(multiDoc);
console.log(JSON.stringify(docs, null, 2));
// [{ "name": "doc1" }, { "name": "doc2" }]

Python (PyYAML)

Python 的 PyYAML 是标准的 YAML 解析器。始终使用 yaml.safe_load() 以防止不受信任的 YAML 执行任意代码:

import yaml
import json

# ===== YAML to JSON =====
yaml_string = """
server:
  host: localhost
  port: 8080
  ssl: true
database:
  name: myapp
  replicas:
    - host: db1.example.com
      port: 5432
    - host: db2.example.com
      port: 5432
  pool:
    min: 5
    max: 20
"""

# Always use safe_load (prevents arbitrary code execution)
data = yaml.safe_load(yaml_string)
json_output = json.dumps(data, indent=2, ensure_ascii=False)
print(json_output)

# ===== JSON to YAML =====
json_string = '{"name": "app", "version": "2.0", "features": ["auth", "logging"]}'
json_data = json.loads(json_string)
yaml_output = yaml.dump(json_data, default_flow_style=False, allow_unicode=True)
print(yaml_output)

# ===== File conversion =====
# YAML file to JSON file
with open('config.yaml', 'r') as yf:
    config = yaml.safe_load(yf)
with open('config.json', 'w') as jf:
    json.dump(config, jf, indent=2)

# JSON file to YAML file
with open('data.json', 'r') as jf:
    data = json.load(jf)
with open('data.yaml', 'w') as yf:
    yaml.dump(data, yf, default_flow_style=False)

# ===== Handle multi-document YAML =====
multi_yaml = """
---
name: doc1
type: config
---
name: doc2
type: data
"""
docs = list(yaml.safe_load_all(multi_yaml))
print(json.dumps(docs, indent=2))

# ===== Preserve key order (Python 3.7+) =====
# dict maintains insertion order by default
ordered = yaml.safe_load(yaml_string)
print(json.dumps(ordered, indent=2))  # keys stay in YAML order

Bash / CLI (yq, python 单行命令)

命令行 YAML 到 JSON 转换中,yq 是最高效的工具。也可以用 Python 或 Ruby 单行命令快速转换:

# ===== yq: YAML processor (like jq for YAML) =====

# Convert YAML file to JSON
yq -o=json config.yaml

# Convert YAML to JSON and save to file
yq -o=json config.yaml > config.json

# Convert JSON to YAML
yq -P config.json

# Convert JSON to YAML and save
yq -P config.json > config.yaml

# Extract a specific field from YAML as JSON
yq -o=json '.server.port' config.yaml

# ===== Python one-liner =====

# YAML to JSON (stdin)
cat config.yaml | python3 -c \
  'import sys,yaml,json; json.dump(yaml.safe_load(sys.stdin),sys.stdout,indent=2)'

# YAML to JSON (file)
python3 -c \
  'import yaml,json; print(json.dumps(yaml.safe_load(open("config.yaml")),indent=2))'

# JSON to YAML
cat data.json | python3 -c \
  'import sys,yaml,json; print(yaml.dump(json.load(sys.stdin),default_flow_style=False))'

# ===== Ruby one-liner =====
ruby -ryaml -rjson -e 'puts JSON.pretty_generate(YAML.load($stdin.read))' < config.yaml

# ===== Pipe YAML from curl to JSON =====
curl -s https://raw.githubusercontent.com/example/repo/main/config.yaml | \
  yq -o=json

# ===== Validate YAML before converting =====
yamllint config.yaml && yq -o=json config.yaml

Go (gopkg.in/yaml.v3)

Go 语言中,gopkg.in/yaml.v3 包提供强大的 YAML 解析支持:

package main

import (
    "encoding/json"
    "fmt"
    "log"

    "gopkg.in/yaml.v3"
)

func main() {
    // YAML input string
    yamlData := []byte(`
server:
  host: localhost
  port: 8080
  ssl: true
database:
  name: myapp
  replicas:
    - host: db1.example.com
      port: 5432
    - host: db2.example.com
      port: 5432
`)

    // Parse YAML into interface{}
    var data interface{}
    err := yaml.Unmarshal(yamlData, &data)
    if err != nil {
        log.Fatalf("YAML parse error: %v", err)
    }

    // Convert map[string]interface{} keys for JSON compatibility
    data = convertMapKeys(data)

    // Marshal to JSON
    jsonData, err := json.MarshalIndent(data, "", "  ")
    if err != nil {
        log.Fatalf("JSON marshal error: %v", err)
    }
    fmt.Println(string(jsonData))
}

// convertMapKeys recursively converts map[interface{}]interface{}
// to map[string]interface{} for JSON compatibility
func convertMapKeys(v interface{}) interface{} {
    switch v := v.(type) {
    case map[string]interface{}:
        result := make(map[string]interface{})
        for key, val := range v {
            result[key] = convertMapKeys(val)
        }
        return result
    case []interface{}:
        for i, val := range v {
            v[i] = convertMapKeys(val)
        }
        return v
    default:
        return v
    }
}

JSON 到 YAML 转换

反方向的 JSON 到 YAML 转换同样重要。当你从 API 接收 JSON 需要存储为 YAML 配置时,或想让 JSON 更具可读性时,这是最佳方案。

注意:注释会丢失。将带注释的 YAML 转为 JSON 再转回 YAML,所有注释将永久丢失。要保留注释,请使用 ruamel.yaml 等专用工具。

最佳实践:(1) 使用 2 空格缩进。(2) 避免流式风格。(3) 引用可能被误解的字符串。(4) 用 YAML 验证器验证输出。

常见 YAML 陷阱与边缘情况

YAML 的灵活性引入了一些坑点。了解这些陷阱有助于编写正确的 YAML:

制表符与空格 — YAML 禁止使用制表符缩进。始终配置编辑器在 YAML 文件中插入空格。

布尔值陷阱 — YAML 1.1 将 yesnoonoff 等解释为布尔值。国家代码 NO(挪威)会变成 false。务必给可能被误读的字符串加引号。

# The YAML boolean trap - these all become true or false in JSON!

# YAML 1.1 boolean values (case-insensitive):
is_active: yes        # → true
is_active: no         # → false
is_active: on         # → true
is_active: off        # → false
is_active: y          # → true
is_active: n          # → false
is_active: true       # → true
is_active: false      # → false

# Real-world problems:
countries:
  - US                # string "US" ✓
  - GB                # string "GB" ✓
  - NO                # boolean false ✗ (Norway disappears!)
  - FR                # string "FR" ✓

# Fix: always quote ambiguous values
countries:
  - "US"
  - "GB"
  - "NO"              # string "NO" ✓
  - "FR"

# Version numbers are also problematic:
version: 1.0          # → float 1 (not string "1.0")
version: "1.0"        # → string "1.0" ✓

多行字符串| 保持换行,> 将换行替换为空格。截断指示符控制尾部换行。

# YAML multiline string variants

# Literal block scalar (|) - preserves newlines
description: |
  This is line one.
  This is line two.
  This is line three.
# JSON: "This is line one.\nThis is line two.\nThis is line three.\n"

# Folded block scalar (>) - replaces newlines with spaces
description: >
  This is a long
  paragraph that will
  be folded into one line.
# JSON: "This is a long paragraph that will be folded into one line.\n"

# Chomping indicators:
keep_trailing: |+     # Keep ALL trailing newlines
  text

strip_trailing: |-    # Strip ALL trailing newlines
  text

clip_trailing: |      # Keep exactly ONE trailing newline (default)
  text

特殊字符 — 值中的冒号、井号、括号和大括号必须加引号以避免解析错误。

锚点和别名 — JSON 转换时完全展开,可能增加文件大小。循环别名可能导致无限循环。

# YAML anchors and aliases

# Define an anchor with &
defaults: &default_settings
  adapter: postgres
  host: localhost
  port: 5432

# Reuse with alias *
development:
  database:
    <<: *default_settings     # Merge key: inherits all defaults
    database: myapp_dev

production:
  database:
    <<: *default_settings     # Same defaults
    database: myapp_prod
    host: db.production.com   # Override specific values

# After JSON conversion (anchors fully expanded):
# {
#   "defaults": { "adapter": "postgres", "host": "localhost", "port": 5432 },
#   "development": {
#     "database": {
#       "adapter": "postgres", "host": "localhost",
#       "port": 5432, "database": "myapp_dev"
#     }
#   },
#   "production": {
#     "database": {
#       "adapter": "postgres", "host": "db.production.com",
#       "port": 5432, "database": "myapp_prod"
#     }
#   }
# }

数字和日期解释1.0 变成浮点数 1 而非字符串 "1.0"。如需字符串,请加引号。

YAML 最佳实践

遵循以下最佳实践,编写干净、可维护的 YAML:

一致的缩进 — 全文使用 2 个空格缩进,与 Kubernetes 和 Docker Compose 的惯例一致。

防御性引用字符串 — 有疑问时就加引号。布尔值、数字、null 和日期格式的值都应该引用。

避免布尔值陷阱 — 特别注意国家代码、开关值和简短回答。使用 linter 自动检查。

Schema 验证 — 使用 JSON Schema 验证 YAML 结构。

使用 yamllint — 在 CI/CD 管道中集成 yamllint 检查常见问题。

# .yamllint.yml configuration example
---
extends: default

rules:
  line-length:
    max: 120
    allow-non-breakable-words: true
  indentation:
    spaces: 2
    indent-sequences: true
  comments:
    min-spaces-from-content: 1
  truthy:
    check-keys: true
    allowed-values: ['true', 'false']
  document-start:
    present: true
  trailing-spaces: enable
  new-line-at-end-of-file: enable

# Run yamllint:
# yamllint .
# yamllint config.yaml
# yamllint -d "{extends: default}" config.yaml

明智地使用注释 — 记住注释在转为 JSON 时会丢失,关键信息也应保存在外部文档中。

常见问题

YAML 和 JSON 有什么区别?

YAML 和 JSON 都是数据序列化格式,但有几个关键区别。YAML 使用基于缩进的语法,支持注释和高级功能(锚点、别名、多行字符串)。JSON 使用括号分隔,不支持注释,数据类型更有限。YAML 更适合人工编辑的配置文件,JSON 更适合 API 和机器通信。YAML 是 JSON 的超集。

如何将 YAML 转换为 JSON?

可通过在线工具、命令行或编程库转换。CLI:安装 yq 执行 "yq -o=json file.yaml"。Python:使用 PyYAML 的 yaml.safe_load 加 json.dumps。JavaScript:使用 js-yaml 加 JSON.stringify。所有方法都是先解析 YAML 为原生数据结构,再序列化为 JSON。

何时使用 YAML,何时使用 JSON?

用 YAML 处理人类频繁编辑的配置文件(Kubernetes、Docker Compose、CI/CD),因其语法清晰、支持注释。用 JSON 处理 API 响应、服务间数据交换和浏览器应用。许多项目同时使用两者:YAML 用于配置,JSON 用于 API 通信。

掌握 YAML 到 JSON 的转换和 YAML 语法对现代 DevOps 和软件开发至关重要。通过理解 YAML 解析器的工作原理、避免布尔值陷阱等常见坑点,并遵循引用和验证的最佳实践,你可以编写出每次都能干净转换为 JSON 的健壮 YAML 配置。

使用我们的免费在线工具即时转换 YAML 与 JSON。

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

Y{}JSON ↔ YAML ConverterYMLYAML Validator & Formatter{ }JSON Formatter🔄YAML ↔ JSON Converter

相关文章

JSON vs YAML vs TOML:你应该用哪种配置格式?

比较 JSON、YAML 和 TOML 配置格式,了解语法、特性和优缺点,选择适合你项目的格式。

YAML 语法与验证:常见错误及修复方法

掌握 YAML 语法:缩进规则、常见解析错误、数据类型和配置文件最佳实践。

YAML 锚点、别名与合并键

使用锚点(&)、别名(*)和合并键(<<)掌握 YAML DRY 原则。减少 Docker Compose、CI/CD 流水线和 Kubernetes 配置中的重复。

JSON 转 YAML 在线转换指南:语法、工具与最佳实践

JSON 与 YAML 转换完整指南。涵盖语法对比、js-yaml、PyYAML、ruamel.yaml、yq 命令行、Kubernetes 清单、Docker Compose、YAML 陷阱(挪威问题、布尔值)及安全最佳实践。