XML 转 YAML 转换器
将 XML 转换为 YAML 格式
XML 输入
YAML 输出
什么是 XML 转 YAML?
XML 转 YAML 是将数据从可扩展标记语言(XML)转换为 YAML Ain't Markup Language(YAML)的过程。XML 使用尖括号标签和属性描述层级数据,而 YAML 通过缩进和纯文本键值对表示相同的结构。将 XML 在线转换为 YAML 是将配置从以 XML 为主的系统(如 Java Spring、Maven 或 .NET)迁移到偏好 YAML 的平台(如 Kubernetes、Ansible、GitHub Actions 和 Docker Compose)时的常见操作。
两种格式的数据模型存在差异。XML 默认将所有内容视为文本,依赖 schema 定义(XSD、DTD)进行类型约束。YAML 拥有原生类型:字符串、整数、浮点数、布尔值、空值、序列(数组)和映射(对象)。在转换过程中,"true"、"5432"、"3.14" 等值可能被解析为 YAML 原生类型,而非保持为字符串。谨慎的转换器会对这些值加引号,以保留原始 XML 中的文本表示。
XML 还支持一些在 YAML 中没有对应物的构造:属性、命名空间、处理指令、CDATA 节和注释。转换时必须为属性选择一种表示约定(通常是带下划线前缀的键,如 _attr),并决定其余构造是丢弃还是展平。在转换前理解这些权衡,有助于选择合适的工具、正确配置并验证 YAML 输出是否忠实还原了原始 XML 的含义。
<server>
<host>db.example.com</host>
<port>5432</port>
<credentials admin="true">
<username>deploy</username>
<password>s3cret</password>
</credentials>
<options>
<option>ssl=true</option>
<option>timeout=30</option>
</options>
</server>server:
host: db.example.com
port: "5432"
credentials:
_admin: "true"
username: deploy
password: s3cret
options:
option:
- ssl=true
- timeout=30为什么使用在线 XML 转 YAML 转换器?
手动编写转换脚本需要处理属性映射、重复元素的数组检测以及 YAML 类型转换的边界情况。基于浏览器的转换器一步完成所有这些工作,让您直接检查 YAML 输出并将其复制到配置文件中。
XML 转 YAML 使用场景
XML 转 YAML 映射参考
XML 和 YAML 的数据模型不同。下表展示了每种 XML 构造如何映射为对应的 YAML。属性通常转换为带下划线前缀的键,重复元素变为 YAML 序列。注释和处理指令等构造在 YAML 中没有对应表示,转换时会被丢弃。
| XML 构造 | XML 示例 | YAML 等价形式 |
|---|---|---|
| Element | <name>text</name> | name: text |
| Nested elements | <a><b>1</b></a> | a:\n b: "1" |
| Attributes | <el attr="v"/> | el:\n _attr: v |
| Text + attributes | <el a="1">text</el> | el:\n _a: "1"\n _text: text |
| Repeated elements | <r><i>1</i><i>2</i></r> | r:\n i:\n - "1"\n - "2" |
| Empty element | <el/> | el: "" |
| CDATA | <![CDATA[raw]]> | Treated as plain text |
| Comments | <!-- note --> | Discarded (no YAML equivalent) |
| Namespaces | xmlns:ns="uri" | Prefix preserved or stripped |
| Boolean-like text | <flag>true</flag> | flag: "true" (quoted to stay string) |
XML 与 YAML:数据模型差异
XML 与 YAML 之间的转换并非简单的语法替换。两种格式在数据表示方式上存在根本性的结构差异,这些差异会影响转换后的数据呈现。
代码示例
以下是在 JavaScript、Python、Go 和命令行中将 XML 转换为 YAML 的可运行示例。每个示例均处理了嵌套元素、属性和重复同级标签。
import { parseStringPromise } from 'xml2js'
import YAML from 'yaml'
const xml = `
<config>
<database host="localhost" port="5432">
<name>mydb</name>
</database>
<features>
<feature>auth</feature>
<feature>logging</feature>
</features>
</config>`
const obj = await parseStringPromise(xml, { explicitArray: false })
console.log(YAML.stringify(obj))
// → config:
// → database:
// → $:
// → host: localhost
// → port: "5432"
// → name: mydb
// → features:
// → feature:
// → - auth
// → - loggingimport xmltodict
import yaml
xml = """
<server>
<host>db.example.com</host>
<port>5432</port>
<replicas>
<replica>node-1</replica>
<replica>node-2</replica>
</replicas>
</server>
"""
# Step 1: XML → Python dict
data = xmltodict.parse(xml)
# Step 2: Python dict → YAML
print(yaml.dump(data, default_flow_style=False))
# → server:
# → host: db.example.com
# → port: '5432'
# → replicas:
# → replica:
# → - node-1
# → - node-2
# With the standard library only (no xmltodict)
import xml.etree.ElementTree as ET
def elem_to_dict(elem):
d = {}
if elem.attrib:
d.update({f"_{k}": v for k, v in elem.attrib.items()})
for child in elem:
val = elem_to_dict(child)
if child.tag in d:
if not isinstance(d[child.tag], list):
d[child.tag] = [d[child.tag]]
d[child.tag].append(val)
else:
d[child.tag] = val
if elem.text and elem.text.strip():
text = elem.text.strip()
return text if not d else {**d, "_text": text}
return d
root = ET.fromstring(xml)
print(yaml.dump({root.tag: elem_to_dict(root)}, default_flow_style=False))# xq is part of the yq package (pip install yq) # It parses XML via xq and outputs JSON, then pipe to yq for YAML echo '<config><host>localhost</host><port>8080</port></config>' | xq . | yq -y . # → config: # → host: localhost # → port: "8080" # Using xmlstarlet + yq (Go version: https://github.com/mikefarah/yq) xmlstarlet sel -t -c '/' input.xml | yq -p=xml -o=yaml # Reads XML from file and outputs YAML directly
package main
import (
"encoding/xml"
"fmt"
"strings"
"gopkg.in/yaml.v3"
)
type Server struct {
XMLName xml.Name `xml:"server"`
Host string `xml:"host" yaml:"host"`
Port int `xml:"port" yaml:"port"`
Options []string `xml:"options>option" yaml:"options"`
}
func main() {
data := `<server>
<host>db.example.com</host>
<port>5432</port>
<options><option>ssl=true</option><option>timeout=30</option></options>
</server>`
var srv Server
xml.NewDecoder(strings.NewReader(data)).Decode(&srv)
out, _ := yaml.Marshal(srv)
fmt.Println(string(out))
// → host: db.example.com
// → port: 5432
// → options:
// → - ssl=true
// → - timeout=30
}