XML to YAML
XMLをYAML形式に変換
XML入力
YAML出力
XMLからYAMLへの変換とは?
XMLからYAMLへの変換とは、Extensible Markup Language(XML)のデータをYAML Ain't Markup Language(YAML)に変換するプロセスです。XMLは階層データを角括弧タグと属性で表現しますが、YAMLは同じ構造をインデントとプレーンテキストのキーと値のペアで表現します。XMLからYAMLへのオンライン変換は、Java Spring、Maven、.NETのようなXML中心のシステムから、Kubernetes、Ansible、GitHub Actions、Docker ComposeといったYAMLを採用するプラットフォームへ設定ファイルを移行する際によく行われる作業です。
2つの形式はデータモデルが異なります。XMLはデフォルトですべてを文字列として扱い、型の強制にはスキーマ定義(XSD、DTD)を使用します。YAMLにはネイティブ型があります:文字列、整数、浮動小数点数、真偽値、null、シーケンス(配列)、マッピング(オブジェクト)です。変換時に「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
}