ما هو تحويل CSV إلى XML؟
يُحوّل تحويل CSV إلى XML القيمَ المفصولة بفواصل إلى مستندات XML (لغة الترميز القابلة للتوسعة). يصبح كل صف في ملف CSV عنصراً في XML، ويُعيَّن كل عنوان عمود اسماً لعنصر فرعي. والنتيجة مستند هرمي يصف نفسه بنفسه، يمكن التحقق من صحته مقابل مخطط (XSD أو DTD) ومعالجته بأدوات XML القياسية كـ XSLT وXPath ومحللات SAX/DOM.
يُعدّ XML معياراً لتبادل البيانات منذ أن نشر W3C مواصفة XML 1.0 عام 1998. وعلى الرغم من أن JSON حلّ محل XML في كثير من واجهات برمجة تطبيقات الويب، إلا أن XML لا يزال الصيغة المطلوبة لخدمات الويب SOAP وتغذيات RSS/Atom ورسومات SVG ومستندات Office Open XML (.docx, .xlsx) وملفات موارد Android وإعدادات بناء Maven/Gradle، فضلاً عن القطاعات المُنظَّمة كالرعاية الصحية (HL7 CDA) والمالية (FpML, XBRL) والحكومة (NIEM). وعندما تكون بياناتك مصدرها جدول بيانات أو تصدير قاعدة بيانات، فإن تحويل CSV إلى XML هو الطريقة المُثلى لإدخالها في هذه الأنظمة.
يجب على أي محوّل صحيح من CSV إلى XML التعامل مع الحالات الحدّية في RFC 4180، كالحقول المقتبسة التي تحتوي على فواصل أو أسطر جديدة، وعلامات الاقتباس المزدوجة المُهرَّبة، والمحددات المتنوعة. أما على صعيد XML، فيجب تهريب الكيانات المُعرَّفة مسبقاً الخمسة (& < > " ')، وتوليد أسماء عناصر صالحة من العناوين باستبدال المسافات والأحرف الخاصة، وإنتاج مخرج صحيح الشكل مع تصريح XML مناسب وترميز موحّد.
لماذا تستخدم محوّل CSV إلى XML؟
كتابة XML يدوياً من بيانات جداول البيانات عملية بطيئة وعرضة للأخطاء. فنسيان وسم إغلاق أو إهمال تهريب علامة & يُنتج XML غير صالح يُعطّل المحللات اللاحقة. يتولى هذا المحوّل التحليل والتهريب وتوليد العناصر في خطوة واحدة.
حالات استخدام تحويل CSV إلى XML
مرجع تعيين CSV إلى XML
يساعدك فهم كيفية تعيين كل جزء من ملف CSV إلى بنية XML على توقع صيغة المخرج وتعديل بياناتك قبل التحويل.
| مفهوم CSV | ما يقابله في XML | التفاصيل |
|---|---|---|
| CSV file | XML document | The entire file maps to a root element containing all records |
| Header row | Element tag names | Each column header becomes the tag name for child elements |
| Data row | <row> element | Each row becomes a repeating child element of the root |
| Cell value | Text node | Cell content becomes the text inside the corresponding tag |
| Empty cell | Empty element or omitted | Can be rendered as <field/> or excluded from output |
| Comma delimiter | XML structure | Delimiters are replaced by element nesting and closing tags |
CSV مقابل XML
CSV صيغة نصية مستوية تعتمد المحددات وتفتقر إلى مخطط مدمج أو أنواع بيانات. أما XML فهو لغة ترميز هرمية تصف نفسها وتدعم المخططات والفضاءات الاسمية والتداخل المعقد. يعتمد الاختيار بينهما على متطلبات النظام الذي سيستقبل البيانات.
أمثلة برمجية
فيما يلي أمثلة عملية لتحويل CSV إلى XML بلغات مختلفة. يُحلّل كل مثال صف العناوين في CSV كأسماء وسوم للعناصر، ويُغلّف كل صف بيانات في عنصر حاوٍ، ويُهرّب كيانات XML في محتوى الخلايا.
// CSV string → XML with proper escaping
const csv = `name,age,city
Alice,30,Berlin
Bob,25,Tokyo`
function csvToXml(csv, rootTag = 'data', rowTag = 'row') {
const rows = csv.trim().split('\n').map(r => r.split(','))
const [headers, ...data] = rows
const xmlRows = data.map(row => {
const fields = headers.map((h, i) => {
const val = (row[i] || '').replace(/&/g, '&')
.replace(/</g, '<').replace(/>/g, '>')
return ` <${h}>${val}</${h}>`
}).join('\n')
return ` <${rowTag}>\n${fields}\n </${rowTag}>`
}).join('\n')
return `<?xml version="1.0" encoding="UTF-8"?>\n<${rootTag}>\n${xmlRows}\n</${rootTag}>`
}
console.log(csvToXml(csv))
// → <?xml version="1.0" encoding="UTF-8"?>
// → <data><row><name>Alice</name><age>30</age>...</row>...</data>import csv, io
from xml.etree.ElementTree import Element, SubElement, tostring
from xml.dom.minidom import parseString
csv_string = """name,age,city
Alice,30,Berlin
Bob,25,Tokyo"""
reader = csv.DictReader(io.StringIO(csv_string))
root = Element('data')
for row in reader:
row_el = SubElement(root, 'row')
for key, value in row.items():
child = SubElement(row_el, key)
child.text = value
# Pretty-print with declaration
raw = tostring(root, encoding='unicode')
pretty = parseString(raw).toprettyxml(indent=' ')
print(pretty)
# → <?xml version="1.0" ?>
# → <data>
# → <row>
# → <name>Alice</name>
# → <age>30</age>
# → <city>Berlin</city>
# → </row>
# → ...
# → </data>package main
import (
"encoding/csv"
"encoding/xml"
"fmt"
"os"
"strings"
)
type Field struct {
XMLName xml.Name
Value string `xml:",chardata"`
}
type Row struct {
XMLName xml.Name `xml:"row"`
Fields []Field
}
type Data struct {
XMLName xml.Name `xml:"data"`
Rows []Row
}
func main() {
input := "name,age,city\nAlice,30,Berlin\nBob,25,Tokyo"
r := csv.NewReader(strings.NewReader(input))
records, _ := r.ReadAll()
headers := records[0]
var data Data
for _, rec := range records[1:] {
row := Row{}
for i, h := range headers {
row.Fields = append(row.Fields, Field{
XMLName: xml.Name{Local: h},
Value: rec[i],
})
}
data.Rows = append(data.Rows, row)
}
out, _ := xml.MarshalIndent(data, "", " ")
fmt.Println(xml.Header + string(out))
// → <?xml version="1.0" encoding="UTF-8"?>
// → <data><row><name>Alice</name>...</row>...</data>
}# Using Python's csv and xml modules via one-liner
python3 -c "
import csv, sys
from xml.etree.ElementTree import Element, SubElement, tostring
from xml.dom.minidom import parseString
reader = csv.DictReader(sys.stdin)
root = Element('data')
for row in reader:
r = SubElement(root, 'row')
for k, v in row.items():
SubElement(r, k).text = v
print(parseString(tostring(root, encoding='unicode')).toprettyxml(indent=' '))
" < data.csv
# Using Miller (mlr) — a dedicated CSV/JSON/XML tool
mlr --icsv --oxml cat data.csv