如何实现YAML与JSON的相互转换(Python/JavaScript完整指南)
如果你经常在配置文件、接口数据和前端调试之间切换,YAML 和 JSON 的互转基本是高频需求。
常见场景通常有这几种:
- DevOps 或微服务配置用 YAML,但接口测试更依赖 JSON
- 浏览器端想做一个在线转换工具,方便临时粘贴测试
- 脚本处理过程中需要把人类可读配置转换成程序更容易消费的格式
这篇文章直接给你可执行方案:
- 用 Python 做命令行批量转换
- 用 JavaScript 做浏览器端实时转换
- 加上验证和排错步骤,避免“看起来成功,实际格式有问题”
为什么要进行YAML与JSON转换?
在微服务架构和DevOps实践中,我们常遇到:
- 配置管理(YAML更适合人类编辑)
- API数据交互(JSON是Web标准格式)
- 多云部署(不同平台格式要求不同)
- 数据持久化(JSON更易压缩存储)
Python实现YAML与JSON高效互转
1.1 准备工作
pip install pyyaml
如果你只是本地测试,直接在虚拟环境里安装即可。
YAML转JSON完整流程
import yaml
import json
import sys
import os
def yaml_to_json(yaml_str):
try:
data = yaml.safe_load(yaml_str)
return json.dumps(data, indent=2, ensure_ascii=False, default=str)
except yaml.YAMLError as e:
print(f"YAML解析错误: {e.problem} {e.context}")
except Exception as e:
print(f"未知错误: {str(e)}")
if __name__ == "__main__":
if len(sys.argv) > 1:
yaml_file = sys.argv[1]
if not os.path.isfile(yaml_file):
print(f"文件不存在: {yaml_file}")
sys.exit(1)
with open(yaml_file, 'r', encoding='utf-8') as f:
yaml_content = f.read()
json_output = yaml_to_json(yaml_content)
json_file = os.path.splitext(yaml_file)[0] + ".json"
with open(json_file, 'w', encoding='utf-8') as f:
f.write(json_output)
print(f"已成功将 YAML 转换为 JSON,输出文件: {json_file}")
else:
# 默认测试数据
yaml_content = """
param:
Author: Yanzhi
Email: yanzhi@bobobk.com
Sample: RNA
Number: 12
Source: Lab
data:
indexdir: /index/
filedir: /rawdata
filenames:
- MERS_set2_0h_1
- MERS_set2_0h_2
- MERS_set2_16h_1
- MERS_set2_16h_2
- MERS_set2_48h_1
- MERS_set2_48h_2
- SARS_0h_1
- SARS_0h_2
- SARS_16h_1
- SARS_16h_2
- SARS_48h_1
- SARS_48h_2
"""
print(yaml_to_json(yaml_content))
{
"param": {
"Author": "Yanzhi",
"Email": "yanzhi@bobobk.com",
"Sample": "RNA",
"Number": 12,
"Source": "Lab"
},
"data": {
"indexdir": "/index/",
"filedir": "/rawdata",
"filenames": [
"MERS_set2_0h_1",
"MERS_set2_0h_2",
"MERS_set2_16h_1",
"MERS_set2_16h_2",
"MERS_set2_48h_1",
"MERS_set2_48h_2",
"SARS_0h_1",
"SARS_0h_2",
"SARS_16h_1",
"SARS_16h_2",
"SARS_48h_1",
"SARS_48h_2"
]
}
}
关键特性说明:
python yaml_to_json.py config.yaml
这类脚本适合批量处理已有配置文件,尤其适用于服务器配置、CI 文件和接口样例数据的清洗。
JSON转YAML高级用法
import json
import yaml
import sys
import os
def json_to_yaml(json_str):
try:
data = json.loads(json_str)
return yaml.dump(data, allow_unicode=True, sort_keys=False)
except json.JSONDecodeError as e:
print(f"JSON解析错误: {e.msg} at line {e.lineno} column {e.colno}")
except Exception as e:
print(f"未知错误: {str(e)}")
if __name__ == "__main__":
if len(sys.argv) > 1:
json_file = sys.argv[1]
if not os.path.isfile(json_file):
print(f"文件不存在: {json_file}")
sys.exit(1)
with open(json_file, 'r', encoding='utf-8') as f:
json_content = f.read()
yaml_output = json_to_yaml(json_content)
yaml_file = os.path.splitext(json_file)[0] + ".yaml"
with open(yaml_file, 'w', encoding='utf-8') as f:
f.write(yaml_output)
print(f"已成功将 JSON 转换为 YAML,输出文件: {yaml_file}")
else:
# 测试 JSON 数据(与前面 YAML 测试数据结构一致)
json_content = """
{
"param": {
"Author": "Yanzhi",
"Email": "yanzhi@bobobk.com",
"Sample": "RNA",
"Number": 12,
"Source": "Lab"
},
"data": {
"indexdir": "/index/",
"filedir": "/rawdata",
"filenames": [
"MERS_set2_0h_1",
"MERS_set2_0h_2",
"MERS_set2_16h_1",
"MERS_set2_16h_2",
"MERS_set2_48h_1",
"MERS_set2_48h_2",
"SARS_0h_1",
"SARS_0h_2",
"SARS_16h_1",
"SARS_16h_2",
"SARS_48h_1",
"SARS_48h_2"
]
}
}
"""
print(json_to_yaml(json_content))
param:
Author: Yanzhi
Email: yanzhi@bobobk.com
Sample: RNA
Number: 12
Source: Lab
data:
indexdir: /index/
filedir: /rawdata
filenames:
- MERS_set2_0h_1
- MERS_set2_0h_2
- MERS_set2_16h_1
- MERS_set2_16h_2
- MERS_set2_48h_1
- MERS_set2_48h_2
- SARS_0h_1
- SARS_0h_2
- SARS_16h_1
- SARS_16h_2
- SARS_48h_1
- SARS_48h_2
如果你需要尽量保留字段顺序,yaml.dump(..., sort_keys=False) 这一步不要删,否则导出的 YAML 顺序会被重排。
JavaScript浏览器端解决方案
浏览器端实现
json to yaml
<script>
function convertToYaml() {
const input = document.getElementById("jsonInput").value;
const output = document.getElementById("yamlOutput");
try {
const obj = JSON.parse(input);
const yaml = jsyaml.dump(obj, { sortKeys: false });
output.textContent = yaml;
} catch (e) {
output.textContent = "❌ JSON 解析错误: " + e.message;
}
}
</script>
yaml to json
function convertToJson() {
const yamlText = document.getElementById("yamlInput").value;
const output = document.getElementById("outputArea");
try {
const obj = jsyaml.load(yamlText);
const json = JSON.stringify(obj, null, 2);
output.textContent = json;
} catch (e) {
output.textContent = "❌ YAML 解析错误: " + e.message;
}
}
如何验证转换结果是否正确
转换完成后,建议至少做下面 3 个检查:
- JSON 结果是否能再次被
json.loads()或浏览器JSON.parse()正常读取 - YAML 结果是否能被
yaml.safe_load()正常解析 - 转换前后的关键字段、数组长度和层级结构是否一致
一个最直接的验证方式是做“往返转换”:
python yaml_to_json.py config.yaml
python json_to_yaml.py config.json
如果往返后结构一致,通常说明转换逻辑没有明显问题。
常见错误与修复
1. YAML 解析报错
最常见原因:缩进不一致、冒号后面缺空格、列表层级写错。
修复方法:
- 统一使用空格缩进,不要混用 tab
- 检查每个键值对是否符合
key: value格式 - 先用最小样例测试,再替换成完整文件
2. JSON 解析报错
最常见原因:多了尾逗号,或字符串没有用双引号包裹。
修复方法:
- 删除对象或数组最后一个元素后的逗号
- 确认字符串使用双引号
- 先在浏览器控制台里跑一次
JSON.parse()定位问题
3. 中文字符变成转义内容
如果导出的 JSON 出现大量 \uXXXX,通常是编码参数没设好。
修复方法:
- Python 输出 JSON 时保留
ensure_ascii=False - 文件读写统一使用
encoding='utf-8'
延伸阅读
如果你后面想把这类转换接到更完整的内容或 SEO 自动化流程里,可以继续看:
总结
YAML 和 JSON 的互转,本质上不是“语法替换”,而是把同一份结构化数据在不同使用场景之间切换。
如果你的重点是批量处理和自动化,优先用 Python;如果你的重点是在线工具和即时预览,浏览器端 JavaScript 更直接。把验证和错误处理补上之后,这类转换脚本才真正适合长期使用。
在线版本
根据 javascript 版本生成 html, 在线yaml json
核心差异与最佳实践
格式对比
| 特性 | YAML | JSON |
|---|---|---|
| 注释 | 支持 # 注释 |
不支持 |
| 数据类型 | 扩展类型(日期、正则) | 基础类型 |
| 可读性 | 高 | 中等 |
| 文件大小 | 较小 | 较大 |
- 需要人工编辑? → 选 YAML
- 需要严格 Schema? → 选 JSON
- 需要跨平台传输? → 选 JSON
- 需要版本控制? → 选 YAML(差异更清晰)
常见问题解决方案
特殊字符转义: JSON中需要转义双引号,YAML支持单双引号混合使用 日期格式处理:
# Python自定义转换器
class SafeDateYamlLoader(yaml.SafeLoader):
pass
def timestamp_constructor(loader, node):
return datetime.fromisoformat(loader.construct_scalar(node))
SafeDateYamlLoader.add_constructor('!datetime', timestamp_constructor)
大文件处理技巧: 分块读取转换
结语
通过本文的详细讲解,相信您已经掌握了:
- 两种语言实现格式转换的核心方法
- 不同场景下的最佳实践选择
- 常见问题的应对策略
实际应用建议:
- 配置管理优先使用 YAML
- API 交互推荐 JSON 格式
- 复杂数据类型注意兼容性
掌握格式转换技能将显著提升您的开发效率,建议结合 获得ChatGPT API 进行自动化脚本开发,构建智能化的数据处理工作流。
- 原文作者:春江暮客
- 原文链接:https://www.bobobk.com/convert-yaml-to-json.html
- 版权声明:本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。