XML إلى JSON
تحويل XML إلى صيغة JSON
إدخال XML
إخراج JSON
ما هو تحويل XML إلى JSON؟
تحويل XML إلى JSON هو عملية تحويل البيانات من لغة الترميز الموسّعة (XML) إلى صيغة كائن JavaScript (JSON). يمثّل كلا التنسيقين بيانات هيكلية هرمية، غير أنهما يستخدمان نحوًا ونماذج بيانات مختلفة. يعتمد XML على وسوم افتتاحية وختامية مع خصائص اختيارية، بينما يعتمد JSON على أزواج مفتاح-قيمة ومصفوفات وأنواع بيانات أولية. يتيح تحويل XML إلى JSON التعامل مع بيانات XML في البيئات التي يكون فيها JSON هو التنسيق الأصلي، كبيئات تشغيل JavaScript وواجهات REST البرمجية وقواعد بيانات NoSQL.
ليس التحويل واحدًا لواحد دائمًا. يحتوي XML على تراكيب لا مقابل مباشر لها في JSON: الخصائص، والمحتوى المختلط (نص متداخل مع عناصر فرعية)، وتعليمات المعالجة، والتعليقات، وأقسام CDATA، وتصريحات مساحات الأسماء. تتعامل مكتبات التحويل المختلفة مع هذه التراكيب بطرق متباينة، وهذا ما أفرز تعدد الاتفاقيات. يتمثّل النهج الأكثر شيوعًا في إضافة بادئة @ لأسماء الخصائص ووضع المحتوى النصي في حقل #text عندما تكون الخصائص موجودة على نفس العنصر.
يُعدّ تحويل XML إلى JSON خطوة شائعة عند الانتقال من SOAP إلى REST، أو استهلاك واجهات برمجة التطبيقات المؤسسية القديمة، أو معالجة تغذيات البيانات الحكومية والمالية التي تشترط XML. بدلًا من إعادة كتابة المنتجين والمستهلكين في آنٍ واحد، تُحوّل الفرق حمولة XML عند طبقة الحدود وتمرّر JSON للخدمات اللاحقة. تدعم AWS API Gateway وApache Camel وMuleSoft هذا النمط بصورة أصلية.
<bookstore>
<book category="fiction">
<title lang="en">The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
<year>1925</year>
<price>10.99</price>
</book>
<book category="non-fiction">
<title lang="en">Sapiens</title>
<author>Yuval Noah Harari</author>
<year>2011</year>
<price>14.99</price>
</book>
</bookstore>{
"bookstore": {
"book": [
{
"@category": "fiction",
"title": {
"@lang": "en",
"#text": "The Great Gatsby"
},
"author": "F. Scott Fitzgerald",
"year": "1925",
"price": "10.99"
},
{
"@category": "non-fiction",
"title": {
"@lang": "en",
"#text": "Sapiens"
},
"author": "Yuval Noah Harari",
"year": "2011",
"price": "14.99"
}
]
}
}لماذا تستخدم محوّل XML إلى JSON الإلكتروني؟
كتابة سكربت تحويل لمرة واحدة تستغرق وقتًا، لا سيما حين يحتوي XML على خصائص ومساحات أسماء أو عناصر متكررة تحتاج إلى تحويلها إلى مصفوفات JSON. يمنحك المحوّل المستند إلى المتصفح مخرجات JSON في ثوانٍ لتتمكن من فحص البنية والمضي قُدُمًا.
حالات استخدام تحويل XML إلى JSON
مرجع ربط XML بـJSON
يمتلك XML وJSON نماذج بيانات مختلفة. يوضح الجدول أدناه كيف يرتبط كل تركيب XML بما يقابله في JSON وفق الاتفاقية الأكثر شيوعًا (@ للخصائص، و#text للنص المصاحب للخصائص). بعض التراكيب كالمحتوى المختلط والتعليقات لا تمتلك تمثيلًا JSON قياسيًا.
| تركيب XML | مثال XML | ما يقابله في JSON |
|---|---|---|
| Element | <name>text</name> | "name": "text" |
| Nested elements | <a><b>1</b></a> | "a": { "b": "1" } |
| Attributes | <el attr="v"/> | "el": { "@attr": "v" } |
| Text + attributes | <el a="1">text</el> | "el": { "@a": "1", "#text": "text" } |
| Repeated elements | <r><i>1</i><i>2</i></r> | "r": { "i": ["1", "2"] } |
| Mixed content | <p>A <b>B</b> C</p> | Varies by convention |
| CDATA | <![CDATA[raw]]> | "#cdata": "raw" or flattened |
| Namespaces | xmlns:prefix="uri" | Prefix preserved or stripped |
| Empty element | <el/> | "el": null or "" |
| Comments | <!-- note --> | Discarded (no JSON equivalent) |
مقارنة اتفاقيات تحويل XML إلى JSON
لا يوجد معيار موحّد يحكم كيفية ربط XML بـJSON. ثمة ثلاث اتفاقيات شائعة الاستخدام، لكل منها مقايضات مختلفة في التعامل مع الخصائص واكتشاف المصفوفات والحفاظ على النص.
أمثلة على الكود
فيما يلي أمثلة عملية لتحويل XML إلى JSON في JavaScript وPython وGo وسطر الأوامر. يتعامل كل مثال مع العناصر المتداخلة والوسوم الشقيقة المتكررة.
// Using the DOMParser API to walk XML and build a JSON object
function xmlToJson(xml) {
const parser = new DOMParser()
const doc = parser.parseFromString(xml, 'application/xml')
function nodeToObj(node) {
const obj = {}
// Handle attributes
if (node.attributes) {
for (const attr of node.attributes) {
obj['@' + attr.name] = attr.value
}
}
// Handle child nodes
for (const child of node.childNodes) {
if (child.nodeType === 3) { // text
const text = child.textContent.trim()
if (text) obj['#text'] = text
} else if (child.nodeType === 1) { // element
const key = child.nodeName
const val = nodeToObj(child)
if (obj[key]) {
if (!Array.isArray(obj[key])) obj[key] = [obj[key]]
obj[key].push(val)
} else {
obj[key] = val
}
}
}
// Simplify text-only nodes
const keys = Object.keys(obj)
if (keys.length === 1 && keys[0] === '#text') return obj['#text']
return obj
}
return nodeToObj(doc.documentElement)
}
const xml = '<user><name>Alice</name><role>admin</role></user>'
console.log(JSON.stringify(xmlToJson(xml), null, 2))
// → { "name": "Alice", "role": "admin" }import xmltodict
import json
xml = """
<user>
<name>Alice</name>
<roles>
<role>admin</role>
<role>editor</role>
</roles>
</user>
"""
# xmltodict converts XML to an OrderedDict
result = xmltodict.parse(xml)
print(json.dumps(result, indent=2))
# → {
# → "user": {
# → "name": "Alice",
# → "roles": { "role": ["admin", "editor"] }
# → }
# → }
# With the standard library (xml.etree.ElementTree)
import xml.etree.ElementTree as ET
def etree_to_dict(elem):
d = {}
if elem.attrib:
d.update({f"@{k}": v for k, v in elem.attrib.items()})
for child in elem:
child_data = etree_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(child_data)
else:
d[child.tag] = child_data
if elem.text and elem.text.strip():
if d:
d["#text"] = elem.text.strip()
else:
return elem.text.strip()
return d
root = ET.fromstring(xml)
print(json.dumps(etree_to_dict(root), indent=2))package main
import (
"encoding/json"
"encoding/xml"
"fmt"
"strings"
)
// For simple, known schemas — define a struct
type User struct {
XMLName xml.Name `xml:"user"`
Name string `xml:"name"`
Roles []string `xml:"roles>role"`
}
func main() {
data := `<user><name>Alice</name><roles><role>admin</role><role>editor</role></roles></user>`
var user User
xml.NewDecoder(strings.NewReader(data)).Decode(&user)
out, _ := json.MarshalIndent(user, "", " ")
fmt.Println(string(out))
// → { "Name": "Alice", "Roles": ["admin", "editor"] }
}# Using xq (part of yq, a jq wrapper for XML)
# Install: pip install yq OR brew install yq
echo '<user><name>Alice</name></user>' | xq .
# → { "user": { "name": "Alice" } }
# Using xmlstarlet + jq
xmlstarlet sel -t -v '//name' input.xml | jq -R '{ name: . }'
# Node.js one-liner with xml2js
echo '<a><b>1</b></a>' | node -e "
const {parseString} = require('xml2js');
let d=''; process.stdin.on('data',c=>d+=c);
process.stdin.on('end',()=>parseString(d,(e,r)=>console.log(JSON.stringify(r,null,2))))
"