XML إلى YAML
تحويل XML إلى صيغة YAML
إدخال XML
إخراج YAML
ما هو تحويل XML إلى YAML؟
تحويل XML إلى YAML هو عملية تحويل البيانات من لغة الترميز الموسّعة (XML) إلى لغة YAML. يعتمد XML على وسوم زاوية مع خصائص لوصف البيانات الهرمية، بينما يمثّل YAML البنى نفسها من خلال المسافات البادئة وأزواج مفتاح-قيمة بصيغة نصية مقروءة. يُعدّ تحويل XML إلى YAML عبر الإنترنت مهمة شائعة عند الانتقال من الأنظمة التي تعتمد XML اعتمادًا كبيرًا كـJava Spring وMaven و.NET إلى منصات تفضّل YAML مثل Kubernetes وAnsible وGitHub Actions وDocker Compose.
يختلف التنسيقان في نموذجَي بياناتهما. يعامل XML كل شيء كنص افتراضيًا ويعتمد على تعريفات المخطط (XSD وDTD) لإنفاذ الأنواع. أما YAML فيمتلك أنواعًا أصلية: سلاسل نصية وأعداد صحيحة وأعداد عشرية وقيم منطقية وقيم فارغة ومتتاليات (مصفوفات) وتعيينات (كائنات). أثناء التحويل، يمكن تفسير قيم مثل "true" و"5432" و"3.14" كأنواع YAML أصلية بدلًا من إبقائها سلاسل نصية. لذا يُضمّن المحوّل الجيد هذه القيم بين اقتباسات للحفاظ على طابعها النصي الأصلي.
يدعم 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 ليس مجرد استبدال صياغة. يمتلك التنسيقان فوارق بنيوية جوهرية تؤثر في طريقة تمثيل البيانات بعد التحويل.
أمثلة على الكود
فيما يلي أمثلة عملية لتحويل XML إلى YAML في JavaScript وPython وGo وسطر الأوامر. يتعامل كل مثال مع العناصر المتداخلة والخصائص والوسوم الشقيقة المتكررة.
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
}