YAML sang XML
Chuyển đổi YAML sang định dạng XML
Đầu vào YAML
Đầu ra XML
Chuyển đổi YAML sang XML là gì?
Chuyển đổi YAML sang XML là quá trình biến đổi dữ liệu được viết bằng YAML (YAML Ain't Markup Language) thành XML (Extensible Markup Language). YAML sử dụng thụt lề và dấu câu tối giản để biểu diễn dữ liệu có cấu trúc, trong khi XML sử dụng thẻ mở và đóng với hệ thống phân cấp tường minh. Chuyển đổi giữa hai định dạng là tác vụ thường gặp khi các hệ thống tiêu thụ XML cần nhận dữ liệu ban đầu được viết bằng YAML.
YAML được thiết kế để con người dễ đọc. Các tệp cấu hình cho những công cụ như Kubernetes, Ansible, Docker Compose và GitHub Actions được viết bằng YAML vì nó gọn gàng và dễ chỉnh sửa thủ công. XML, được định nghĩa theo đặc tả W3C XML 1.0, là định dạng trao đổi dữ liệu mặc định trong các hệ thống doanh nghiệp, dịch vụ web SOAP và quy trình xử lý tài liệu trong nhiều thập kỷ. Khi một cấu hình được viết bằng YAML cần đưa vào pipeline dựa trên XML, việc chuyển đổi là bắt buộc.
Ánh xạ giữa YAML và XML không phải là một-một. YAML hỗ trợ các kiểu dữ liệu như boolean, số nguyên, số thực và null theo cách tự nhiên, trong khi XML coi mọi nội dung là văn bản trừ khi một schema (XSD hoặc DTD) định nghĩa kiểu bên ngoài. Các chuỗi YAML (danh sách) không có tương đương trực tiếp trong XML và phải được biểu diễn dưới dạng các phần tử lặp lại. Hiểu những khác biệt này giúp bạn dự đoán đầu ra và tránh bất ngờ.
Tại sao sử dụng công cụ chuyển đổi YAML sang XML này?
Viết lại thủ công YAML dưới dạng XML rất tẻ nhạt và dễ gây lỗi, đặc biệt với các cấu trúc lồng nhau sâu. Công cụ chuyển đổi này xử lý việc dịch cấu trúc ngay lập tức.
Các trường hợp sử dụng YAML sang XML
Tài liệu tham khảo ánh xạ kiểu dữ liệu YAML sang XML
Các kiểu dữ liệu YAML không ánh xạ trực tiếp sang XML. Bảng này cho thấy cách mỗi cấu trúc YAML được dịch sang tương đương XML. Hiểu các quy tắc này giúp bạn dự đoán đầu ra và xử lý các kết quả không mong đợi.
| Kiểu YAML | Ví dụ YAML | Đầu ra XML |
|---|---|---|
| Mapping (key: value) | { name: Alice } | <name>Alice</name> |
| Sequence (- item) | - apple\n- banana | <item>apple</item><item>banana</item> |
| Nested mapping | user:\n name: Alice | <user><name>Alice</name></user> |
| Scalar (string) | greeting: hello world | <greeting>hello world</greeting> |
| Scalar (number) | count: 42 | <count>42</count> |
| Scalar (boolean) | active: true | <active>true</active> |
| Null | value: null | <value/> |
| Multiline string | bio: |\n Line one\n Line two | <bio>Line one\nLine two</bio> |
YAML và XML: Sự khác biệt về định dạng
YAML và XML giải quyết cùng một vấn đề — biểu diễn dữ liệu có cấu trúc — với những đánh đổi khác nhau. Không định dạng nào vượt trội hoàn toàn; lựa chọn đúng phụ thuộc vào ai hoặc cái gì tiêu thụ dữ liệu.
| Tính năng | YAML | XML |
|---|---|---|
| Cú pháp | Dựa trên thụt lề | Dựa trên thẻ (<tag>...</tag>) |
| Kiểu dữ liệu | Tự nhiên (string, int, bool, null, float) | Chỉ văn bản (schema thêm kiểu) |
| Ghi chú | # ghi chú nội tuyến | <!-- ghi chú khối --> |
| Thuộc tính | Không hỗ trợ tự nhiên | Có (<tag attr="val">) |
| Không gian tên | Không hỗ trợ | Có (xmlns:prefix) |
| Kích thước tệp | Nhỏ hơn (không có thẻ đóng) | Lớn hơn (thẻ dài dòng) |
Ví dụ code
Cách chuyển đổi YAML sang XML theo chương trình trong các ngôn ngữ và môi trường khác nhau:
import { parseDocument } from 'yaml'
import { js2xml } from 'xml-js'
const yamlStr = `
server:
host: localhost
port: 8080
ssl: true
`
const data = parseDocument(yamlStr).toJSON()
const xml = js2xml({ root: data }, { compact: true, spaces: 2 })
console.log(xml)
// → <root>
// → <server>
// → <host>localhost</host>
// → <port>8080</port>
// → <ssl>true</ssl>
// → </server>
// → </root>import yaml
import xml.etree.ElementTree as ET
yaml_str = """
database:
host: db.example.com
port: 5432
credentials:
user: admin
password: secret
"""
data = yaml.safe_load(yaml_str)
def dict_to_xml(tag, d):
elem = ET.Element(tag)
for key, val in d.items():
child = ET.SubElement(elem, key)
if isinstance(val, dict):
child.extend(dict_to_xml(key, val))
elem.remove(child)
elem.append(dict_to_xml(key, val))
else:
child.text = str(val)
return elem
root = dict_to_xml('root', data)
ET.indent(root, space=' ')
print(ET.tostring(root, encoding='unicode'))
# → <root>
# → <database>
# → <host>db.example.com</host>
# → <port>5432</port>
# → ...
# → </database>
# → </root>package main
import (
"encoding/xml"
"fmt"
"gopkg.in/yaml.v3"
)
type Server struct {
XMLName xml.Name `xml:"server"`
Host string `yaml:"host" xml:"host"`
Port int `yaml:"port" xml:"port"`
SSL bool `yaml:"ssl" xml:"ssl"`
}
func main() {
yamlData := []byte("host: localhost\nport: 8080\nssl: true")
var s Server
yaml.Unmarshal(yamlData, &s)
xmlBytes, _ := xml.MarshalIndent(s, "", " ")
fmt.Println(xml.Header + string(xmlBytes))
// → <?xml version="1.0" encoding="UTF-8"?>
// → <server>
// → <host>localhost</host>
// → <port>8080</port>
// → <ssl>true</ssl>
// → </server>
}# Using yq (YAML processor) with xq (XML wrapper around jq) # Install: pip install yq # Convert YAML file to XML yq -x . config.yaml # → <host>localhost</host><port>8080</port> # Pipe inline YAML through conversion echo "name: Alice" | yq -x . # → <name>Alice</name>