XML sang YAML
Chuyển đổi XML sang định dạng YAML
Nhập XML
Xuất YAML
Chuyển đổi XML sang YAML là gì?
Chuyển đổi XML sang YAML là quá trình biến đổi dữ liệu từ Extensible Markup Language (XML) sang YAML Ain't Markup Language (YAML). XML dùng thẻ dấu ngoặc nhọn kèm thuộc tính để mô tả dữ liệu phân cấp, trong khi YAML biểu diễn cùng cấu trúc đó thông qua thụt lề và cặp khóa-giá trị dạng văn bản thuần. Chuyển đổi XML sang YAML trực tuyến là tác vụ phổ biến khi di chuyển cấu hình từ các hệ thống nặng XML như Java Spring, Maven hoặc .NET sang các nền tảng ưu tiên YAML như Kubernetes, Ansible, GitHub Actions và Docker Compose.
Hai định dạng khác nhau ở mô hình dữ liệu. XML mặc định coi mọi thứ là văn bản và dựa vào định nghĩa schema (XSD, DTD) để ràng buộc kiểu. YAML có kiểu dữ liệu gốc: chuỗi, số nguyên, số thực, boolean, null, dãy (mảng) và ánh xạ (đối tượng). Khi chuyển đổi, các giá trị như "true", "5432" và "3.14" có thể được hiểu là kiểu gốc YAML thay vì giữ nguyên dạng chuỗi. Một công cụ chuyển đổi cẩn thận sẽ đặt dấu ngoặc kép cho các giá trị này để bảo toàn biểu diễn văn bản gốc từ XML.
XML cũng hỗ trợ các cấu trúc không có tương đương trong YAML: thuộc tính, không gian tên, chỉ thị xử lý, phần CDATA và chú thích. Quá trình chuyển đổi phải chọn quy ước biểu diễn thuộc tính (thường là khóa có tiền tố gạch dưới như _attr) và quyết định bỏ qua hay làm phẳng phần còn lại. Hiểu các đánh đổi này trước khi chuyển đổi giúp bạn chọn công cụ phù hợp, cấu hình đúng và xác minh rằng đầu ra YAML phản ánh đúng ý nghĩa của XML gốc.
<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=30Tại sao sử dụng công cụ chuyển đổi XML sang YAML trực tuyến?
Tự viết script chuyển đổi đòi hỏi phải xử lý ánh xạ thuộc tính, phát hiện mảng cho các phần tử lặp lại và các trường hợp đặc biệt về ép kiểu YAML. Một công cụ chạy trên trình duyệt xử lý tất cả những điều đó chỉ trong một bước, cho phép bạn kiểm tra đầu ra YAML và sao chép trực tiếp vào các tệp cấu hình.
Các trường hợp sử dụng chuyển đổi XML sang YAML
Tham chiếu ánh xạ XML sang YAML
XML và YAML có mô hình dữ liệu khác nhau. Bảng dưới đây cho thấy cách mỗi cấu trúc XML ánh xạ sang tương đương YAML. Thuộc tính thường được chuyển sang khóa có tiền tố gạch dưới, và các phần tử lặp lại trở thành dãy YAML. Một số cấu trúc như chú thích và chỉ thị xử lý không có biểu diễn YAML và bị loại bỏ trong quá trình chuyển đổi.
| Cấu trúc XML | Ví dụ XML | Tương đương 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 vs YAML: Sự khác biệt mô hình dữ liệu
Chuyển đổi giữa XML và YAML không phải là thay thế cú pháp đơn giản. Hai định dạng có sự khác biệt cấu trúc cơ bản ảnh hưởng đến cách dữ liệu được biểu diễn sau khi chuyển đổi.
Ví dụ mã nguồn
Dưới đây là các ví dụ hoạt động để chuyển đổi XML sang YAML trong JavaScript, Python, Go và dòng lệnh. Mỗi ví dụ xử lý các phần tử lồng nhau, thuộc tính và các thẻ anh em lặp lại.
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
}