DevToolBox免费
博客

YAML 转 JSON:在线转换与 JavaScript、Python、CLI 工具指南

7 分钟阅读作者 DevToolBox

YAML 转 JSON:在线转换与 JavaScript、Python、CLI 工具指南

在线及编程方式将 YAML 转换为 JSON。JavaScript、Python、Go 和命令行 YAML 转 JSON 完整指南。

TL;DR

YAML 是人类可读的配置格式,JSON 是 API 的通用语言。在线转换用 DevToolBox 的免费工具;代码中用 js-yaml(JavaScript)、PyYAML(Python)或 gopkg.in/yaml.v3(Go);命令行用 yq。注意 YAML 的布尔陷阱(yes/no/on/off)、制表符禁止、锚点展开等常见坑。多文档 YAML(---分隔)转换为 JSON 数组。

YAML 与 JSON — 核心区别

YAML(YAML Ain't Markup Language)和 JSON(JavaScript Object Notation)都是数据序列化格式,但设计哲学截然不同。YAML 面向人类编辑,以缩进表示层次;JSON 面向机器解析,语法严格无歧义。下表对比两者在实际使用中的关键差异:

特性YAMLJSON
可读性极佳,缩进语法,无多余标点中等,大量引号和括号
注释支持支持(# 开头)不支持
数据类型字符串、整数、浮点数、布尔、null、日期、二进制字符串、数字、布尔、null、数组、对象
文件大小通常更小(无引号和括号)稍大(需引号和括号)
解析速度较慢(缩进敏感解析)较快(语法简单)
典型用途Kubernetes、Docker Compose、CI/CD、AnsibleREST API、数据库、程序间通信

在线转换

最快的 YAML 转 JSON 方式是使用在线工具。DevToolBox 的 YAML to JSON 转换器支持实时预览、错误高亮和格式化输出——无需安装任何依赖。适合临时转换、调试配置文件或验证 YAML 语法。

对于需要集成到工程中的场景,请继续阅读以下各语言的代码示例和命令行方法。

JavaScript / Node.js — 使用 js-yaml

js-yaml 是 JavaScript 生态中最流行的 YAML 解析库,兼容 Node.js 和浏览器环境。核心 API 是 yaml.load()(解析 YAML → JS 对象)和 JSON.stringify()(序列化为 JSON)。

安装:

npm install js-yaml
# TypeScript types are bundled — no @types needed

基本用法:

const yaml = require('js-yaml');

const yamlString = `
name: my-app
version: 1.0.0
database:
  host: localhost
  port: 5432
  credentials:
    user: admin
    password: secret
features:
  - auth
  - logging
  - metrics
enabled: true
`;

// Parse YAML → JavaScript object
const obj = yaml.load(yamlString);

// Serialize to JSON (pretty-printed with 2-space indent)
const json = JSON.stringify(obj, null, 2);
console.log(json);

/* Output:
{
  "name": "my-app",
  "version": "1.0.0",
  "database": {
    "host": "localhost",
    "port": 5432,
    "credentials": {
      "user": "admin",
      "password": "secret"
    }
  },
  "features": ["auth", "logging", "metrics"],
  "enabled": true
}
*/

从文件读取并转换:

const yaml = require('js-yaml');
const fs = require('fs');
const path = require('path');

function yamlFileToJson(inputPath, outputPath) {
  // Read YAML file
  const yamlContent = fs.readFileSync(inputPath, 'utf8');

  // Parse and convert
  const obj = yaml.load(yamlContent);
  const jsonContent = JSON.stringify(obj, null, 2);

  // Write JSON file
  if (outputPath) {
    fs.writeFileSync(outputPath, jsonContent, 'utf8');
    console.log(`Converted ${inputPath} → ${outputPath}`);
  }

  return jsonContent;
}

// Usage
yamlFileToJson('config.yaml', 'config.json');
yamlFileToJson('k8s-deployment.yaml', 'k8s-deployment.json');

处理多文档 YAML(--- 分隔符):

const yaml = require('js-yaml');

const multiDocYaml = `
---
kind: Deployment
metadata:
  name: api-server
---
kind: Service
metadata:
  name: api-service
---
kind: ConfigMap
metadata:
  name: api-config
`;

// yaml.load() only parses the FIRST document
// Use yaml.loadAll() for multi-document YAML
const documents = yaml.loadAll(multiDocYaml);

console.log(`Found ${documents.length} documents`);
// Convert the document array to JSON
const json = JSON.stringify(documents, null, 2);
console.log(json);

// Or process each document individually
documents.forEach((doc, index) => {
  console.log(`Document ${index + 1}: ${doc.kind}`);
});

Python — 使用 PyYAML

PyYAML 是 Python 的标准 YAML 库。始终使用 yaml.safe_load() 而非 yaml.load(),以防止来自不可信 YAML 的任意代码执行。

安装:

pip install pyyaml

基本转换:

import yaml
import json

yaml_string = """
server:
  host: 0.0.0.0
  port: 8080
  timeout: 30
database:
  url: postgres://localhost/mydb
  pool_size: 10
  ssl: true
logging:
  level: info
  format: json
tags:
  - production
  - api
  - v2
"""

# Parse YAML safely (prevents code execution from untrusted YAML)
data = yaml.safe_load(yaml_string)

# Serialize to JSON with indentation
json_output = json.dumps(data, indent=2)
print(json_output)

# Output:
# {
#   "server": { "host": "0.0.0.0", "port": 8080, "timeout": 30 },
#   "database": { "url": "postgres://localhost/mydb", "pool_size": 10, "ssl": true },
#   "logging": { "level": "info", "format": "json" },
#   "tags": ["production", "api", "v2"]
# }

转换文件:

import yaml
import json
import sys
from pathlib import Path

def yaml_to_json(input_path: str, output_path: str = None) -> str:
    """Convert a YAML file to JSON."""
    with open(input_path, 'r', encoding='utf-8') as f:
        data = yaml.safe_load(f)

    json_str = json.dumps(data, indent=2, ensure_ascii=False)

    if output_path:
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(json_str)
        print(f"Converted {input_path} → {output_path}")

    return json_str

# Convert a single file
result = yaml_to_json("config.yaml", "config.json")

# Convert multiple files in a directory
for yaml_file in Path(".").glob("**/*.yaml"):
    json_file = yaml_file.with_suffix(".json")
    yaml_to_json(str(yaml_file), str(json_file))

多文档 YAML(yaml.safe_load_all):

import yaml
import json

multi_doc_yaml = """
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-api
spec:
  replicas: 3
---
apiVersion: v1
kind: Service
metadata:
  name: web-api-svc
spec:
  type: ClusterIP
  port: 80
"""

# yaml.safe_load() only reads the first document
# yaml.safe_load_all() returns a generator for all documents
documents = list(yaml.safe_load_all(multi_doc_yaml))

print(f"Found {len(documents)} documents")
# Serialize the entire array to JSON
print(json.dumps(documents, indent=2))

命令行工具

命令行转换适合 Shell 脚本、CI/CD 管道和快速一次性操作。以下是最常用的几种方式:

yq (推荐):

# Install yq (macOS)
brew install yq

# 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

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

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

# Pretty-print with indentation
yq -o json -P config.yaml

# Convert from stdin
cat config.yaml | yq -o json

# Process specific keys during conversion
yq -o json '.database' config.yaml

# Convert multiple files
for f in *.yaml; do yq -o json "$f" > "${f%.yaml}.json"; done

Python 一行命令(无需额外安装):

# Convert YAML stdin to JSON stdout
cat file.yaml | python3 -c "import yaml,json,sys; print(json.dumps(yaml.safe_load(sys.stdin), indent=2))"

# Convert YAML file to JSON file
python3 -c "
import yaml, json
with open('input.yaml') as f:
    data = yaml.safe_load(f)
with open('output.json', 'w') as f:
    json.dump(data, f, indent=2)
"

# One-liner with file args
python3 -c "import yaml,json,sys; json.dump(yaml.safe_load(open(sys.argv[1])), open(sys.argv[2],'w'), indent=2)" input.yaml output.json

Ruby 一行命令:

# Ruby one-liner (available on most Unix systems)
ruby -ryaml -rjson -e 'puts JSON.pretty_generate(YAML.safe_load(STDIN.read))' < file.yaml

YAML 数据类型映射到 JSON

了解 YAML 类型如何映射到 JSON 是避免转换错误的关键。以下表格展示了常见的类型映射:

YAML 值JSON 输出说明
null, ~, (empty)nullYAML 空值
true, falsetrue, falseYAML 1.1/1.2 布尔值
yes, no, on, offtrue, false仅 YAML 1.1 视为布尔
42, -742, -7整数
3.14, 1.0e103.14, 1.0e10浮点数
0777 (octal)511八进制 → 十进制整数
0xFF (hex)255十六进制 → 十进制整数
"hello", 'world'"hello", "world"字符串(引号可选)
!!binary <base64>"<base64>"二进制数据 → base64 字符串
&anchor, *alias展开的值锚点/别名完全展开
- item1 - item2["item1", "item2"]序列 → JSON 数组
key: value{"key": "value"}映射 → JSON 对象

YAML 锚点与别名

YAML 锚点(&)允许定义可复用的数据块,别名(*)引用它们。转换为 JSON 时,所有别名都会完全展开(内联替换),没有引用机制。合并键(<<: *base)也会展开,允许重复键以后者为准。

转换前(YAML):

# YAML with anchors and aliases
defaults: &defaults
  timeout: 30
  retries: 3
  log_level: info

production:
  <<: *defaults          # Merge: inherits timeout, retries, log_level
  log_level: warning     # Override: replaces log_level from defaults
  replicas: 5

staging:
  <<: *defaults          # Merge: inherits all defaults
  replicas: 1

# Simple alias (not merge key)
base_image: &img "node:20-alpine"
services:
  web:
    image: *img          # Alias: becomes "node:20-alpine"
  worker:
    image: *img          # Alias: also becomes "node:20-alpine"

转换后(JSON)— 锚点完全展开:

{
  "defaults": { "timeout": 30, "retries": 3, "log_level": "info" },
  "production": {
    "timeout": 30,
    "retries": 3,
    "log_level": "warning",
    "replicas": 5
  },
  "staging": {
    "timeout": 30,
    "retries": 3,
    "log_level": "info",
    "replicas": 1
  },
  "base_image": "node:20-alpine",
  "services": {
    "web": { "image": "node:20-alpine" },
    "worker": { "image": "node:20-alpine" }
  }
}

注意:JSON 文件比 YAML 大,因为每个别名引用的值都被完全复制。在有大量锚点复用的场景下,这可能显著增加 JSON 体积。

多文档 YAML

YAML 支持在单个文件中包含多个文档,用 --- 分隔。这在 Kubernetes 中极为常见(一个 YAML 文件包含 Deployment + Service)。转换为 JSON 时,多文档变成 JSON 数组。

# Multi-document YAML (common in Kubernetes)
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 8080

JavaScript — yaml.loadAll():

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

const content = fs.readFileSync('k8s-manifests.yaml', 'utf8');

// yaml.load() → only parses FIRST document (wrong for multi-doc)
// yaml.loadAll() → parses ALL documents into an array
const documents = yaml.loadAll(content);

console.log(JSON.stringify(documents, null, 2));
// Result: [{ apiVersion: "apps/v1", kind: "Deployment", ... }, { apiVersion: "v1", kind: "Service", ... }]

yq 命令行:

# yq automatically handles multi-document YAML
# Outputs as JSON array
yq -o json k8s-manifests.yaml

# Split into individual JSON files
yq -o json '.' k8s-manifests.yaml | jq -c '.[]' | while read doc; do
  kind=$(echo "$doc" | jq -r '.kind')
  echo "$doc" | jq . > "${kind,,}.json"
done

Go — gopkg.in/yaml.v3 + encoding/json

Go 使用 gopkg.in/yaml.v3 解析 YAML,encoding/json(标准库)序列化 JSON。强类型使转换显式可控。可用 interface{} 动态处理,也可定义结构体以获得类型安全。

// go get gopkg.in/yaml.v3

package main

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

    "gopkg.in/yaml.v3"
)

// Dynamic approach — works for any YAML structure
func yamlToJsonDynamic(yamlBytes []byte) ([]byte, error) {
    // Step 1: Parse YAML into generic interface{}
    var obj interface{}
    if err := yaml.Unmarshal(yamlBytes, &obj); err != nil {
        return nil, fmt.Errorf("yaml parse error: %w", err)
    }

    // Step 2: Serialize to JSON
    jsonBytes, err := json.MarshalIndent(obj, "", "  ")
    if err != nil {
        return nil, fmt.Errorf("json marshal error: %w", err)
    }

    return jsonBytes, nil
}

// Struct-based approach — type-safe, best for known schemas
type Config struct {
    Name    string `yaml:"name" json:"name"`
    Version string `yaml:"version" json:"version"`
    Server  struct {
        Host string `yaml:"host" json:"host"`
        Port int    `yaml:"port" json:"port"`
    } `yaml:"server" json:"server"`
    Features []string `yaml:"features" json:"features"`
}

func main() {
    yamlContent := []byte(`
name: my-service
version: "2.1.0"
server:
  host: 0.0.0.0
  port: 8080
features:
  - auth
  - rate-limiting
  - tracing
`)

    // Dynamic approach
    jsonBytes, err := yamlToJsonDynamic(yamlContent)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v\n", err)
        os.Exit(1)
    }
    fmt.Println(string(jsonBytes))

    // Struct-based approach
    var cfg Config
    if err := yaml.Unmarshal(yamlContent, &cfg); err != nil {
        panic(err)
    }
    out, _ := json.MarshalIndent(cfg, "", "  ")
    fmt.Println(string(out))
}

Kubernetes 和 CI/CD 使用场景

将 YAML 转换为 JSON 在 DevOps 工作流中有多种实际应用:

1. 通过 Kubernetes API 操作资源:

# kubectl can apply both YAML and JSON
# Convert k8s manifest YAML to JSON for API calls
yq -o json deployment.yaml > deployment.json

# Use with curl to call the Kubernetes API directly
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  https://$K8S_API/apis/apps/v1/namespaces/default/deployments \
  -d @deployment.json

# Validate manifest before applying
kubectl apply --dry-run=client -f deployment.yaml
yq -o json deployment.yaml | kubectl apply --dry-run=client -f -

2. GitHub Actions 工作流转换:

# GitHub Actions step to convert YAML config to JSON for downstream tools
- name: Convert YAML config to JSON
  run: |
    pip install pyyaml
    python3 -c "
    import yaml, json
    with open('config.yaml') as f:
        data = yaml.safe_load(f)
    with open('config.json', 'w') as f:
        json.dump(data, f, indent=2)
    "
    echo "Config converted:"
    cat config.json

# Or using yq in GitHub Actions
- name: Convert with yq
  uses: mikefarah/yq@master
  with:
    cmd: yq -o json config.yaml > config.json

3. Helm values.yaml 转 JSON(用于 Terraform):

# Convert Helm values.yaml to JSON for use in Terraform helm_release
yq -o json values.yaml > values.json

# In Terraform:
# resource "helm_release" "app" {
#   values = [file("values.json")]
# }

# Or generate Terraform variables from YAML config
python3 -c "
import yaml, json
with open('app-config.yaml') as f:
    config = yaml.safe_load(f)

# Write as Terraform tfvars JSON
with open('terraform.tfvars.json', 'w') as f:
    json.dump(config, f, indent=2)
"

常见陷阱与注意事项

1. 布尔陷阱(YAML 1.1)

YAML 1.1 将大量值视为布尔值。这是最常见的转换错误来源:

# YAML 1.1 boolean trap — these all become true or false in JSON!
country: NO           # → false  (Norway country code!)
debug: yes            # → true
feature_flag: on      # → true
cache: off            # → false
verbose: y            # → true  (short form)
quiet: n              # → false (short form)

# Fix: always quote ambiguous strings
country: "NO"         # → "NO"  (string)
debug: "yes"          # → "yes" (string)
feature_flag: "on"    # → "on"  (string)

# YAML 1.2 only treats these as booleans:
# true, false (case-insensitive)
# All other values are strings

2. 八进制数字(0777 → 511)

# File permissions as octal numbers become decimal integers!
chmod_value: 0777    # → 511 in JSON (not "0777"!)
umask: 022           # → 22 in JSON

# Fix: quote the value to keep it as a string
chmod_value: "0777"  # → "0777" (string)
umask: "022"         # → "022" (string)

# Or use explicit YAML tag
chmod_value: !!str 0777  # → "0777"

3. 多行字符串(| 字面量 vs > 折叠)

# Literal block (|) — preserves newlines exactly
script: |
  #!/bin/bash
  echo "Starting..."
  npm install
  npm test
# JSON: "#!/bin/bash
echo "Starting..."
npm install
npm test
"

# Folded block (>) — joins lines with spaces (like HTML)
description: >
  This is a long
  description that
  wraps across lines.
# JSON: "This is a long description that wraps across lines.
"

# Chomping indicators control trailing newlines:
# | (default) → keeps exactly one trailing newline
# |- → strips all trailing newlines
# |+ → keeps all trailing newlines

4. 制表符禁止使用

# WRONG: tabs cause parse errors
server:
	host: localhost    # ← tab character → YAML parse error!
	port: 8080

# CORRECT: always use spaces (2 is the convention)
server:
  host: localhost    # ← 2 spaces
  port: 8080

# Configure your editor to insert spaces (not tabs) for .yaml files
# .editorconfig:
# [*.{yaml,yml}]
# indent_style = space
# indent_size = 2

反向转换:JSON 转 YAML

将 JSON 转换为 YAML 同样简单。每个主流 YAML 库都支持此方向。注意:JSON 转 YAML 再转回 JSON 时,注释和格式会丢失。

JavaScript (js-yaml):

const yaml = require('js-yaml');

const jsonObj = {
  name: "my-app",
  version: "1.0.0",
  server: { host: "0.0.0.0", port: 8080 },
  features: ["auth", "logging"]
};

// yaml.dump() converts JS object → YAML string
const yamlOutput = yaml.dump(jsonObj, {
  indent: 2,        // 2-space indentation
  lineWidth: 120,   // wrap at 120 chars
  noRefs: true,     // don't use aliases in output
});

console.log(yamlOutput);
// name: my-app
// version: 1.0.0
// server:
//   host: 0.0.0.0
//   port: 8080
// features:
//   - auth
//   - logging

Python (PyYAML):

import yaml
import json

json_string = '{"name":"my-app","server":{"host":"localhost","port":8080},"tags":["api","v2"]}'
data = json.loads(json_string)

# yaml.dump() serializes Python dict → YAML string
yaml_output = yaml.dump(data, default_flow_style=False, indent=2, allow_unicode=True)
print(yaml_output)
# name: my-app
# server:
#   host: localhost
#   port: 8080
# tags:
# - api
# - v2

yq 反向转换:

# Convert JSON to YAML with yq
yq -oy config.json            # -o yaml (can also use --output-format=yaml)
yq -oy config.json > config.yaml

# Convert JSON stdin to YAML
echo '{"name":"app","port":3000}' | yq -oy
核心要点
  • YAML 用于人类编辑的配置文件(Kubernetes、Docker Compose、GitHub Actions);JSON 用于 API 和机器间通信。
  • 在线转换用 DevToolBox 的免费工具;代码中用 js-yaml (JS)、PyYAML (Python)、gopkg.in/yaml.v3 (Go);命令行用 yq。
  • Python 中始终使用 yaml.safe_load() — yaml.load() 对不可信输入存在任意代码执行风险。
  • 布尔陷阱:YAML 1.1 中 yes/no/on/off/y/n 都是布尔值。总是引用可能被误读的字符串。
  • YAML 锚点(&)和别名(*)在 JSON 转换时完全展开,JSON 输出可能比 YAML 源文件大。
  • 多文档 YAML(--- 分隔)用 yaml.loadAll() 或 yaml.safe_load_all() 处理,转换为 JSON 数组。
  • YAML 禁止使用制表符缩进——总是用空格(2个空格是惯例)。用 .editorconfig 在编辑器中强制执行。
𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

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

无垃圾邮件,随时退订。

试试这些相关工具

Y→YAML to JSON Converter{ }JSON FormatterJSON Validator

相关文章

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

免费在线 YAML 转 JSON 转换器。学习 YAML 语法,在 YAML 和 JSON 之间转换,含 JavaScript、Python、Go、Bash 代码示例。

YAML vs JSON:语法对比、使用场景与格式转换

比较 YAML 和 JSON 语法、特性和使用场景。了解 YAML 锚点、多行字符串、Docker/Kubernetes 配置,以及格式之间的转换方法。

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

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