العمل مع XML في Go (Golang): حزمة encoding/xml والبدائل

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة في معالجة XML بلغة Go



توفر لغة Go (Golang) طريقة قوية وأنيقة للعمل مع XML من خلال الحزمة القياسية encoding/xml. تنفذ هذه الحزمة واجهة بسيطة لقراءة (تحليل) وكتابة (تسلسل) مستندات XML، باستخدام التعليقات التوضيحية للهياكل (struct tags). على عكس العديد من اللغات الأخرى، لا تتطلب Go إنشاء محللات DOM أو SAX منفصلة – يكفي وصف بنية البيانات، وتقوم الحزمة تلقائيًا بمطابقة علامات XML مع الحقول.



في هذه المقالة، سنشرح بالتفصيل الإمكانيات الرئيسية للحزمة encoding/xml، بدءًا من التحليل الأساسي وصولاً إلى التقنيات المتقدمة: معالجة السمات، مساحات الأسماء، القراءة التدفقية للملفات الكبيرة، وتوليد XML. كما سنستعرض المكتبات الخارجية الشائعة التي قد تكون مفيدة في سيناريوهات محددة.



الأساسيات: تحليل XML إلى هياكل Go



الطريقة الأكثر شيوعًا للعمل مع XML في Go هي إلغاء التسلسل (unmarshal) لبيانات XML إلى مثيلات من الهياكل. يتم استخدام الدالة xml.Unmarshal() لهذا الغرض. الميزة الأساسية هي استخدام العلامات xml:"..." في تعريف حقول الهيكل.



مثال بسيط: تحليل خلاصة RSS



package main

import ( "encoding/xml" "fmt")

// هيكل لعنصر RSStype RSS struct { XMLName xml.Name `xml:"rss"` Channel Channel `xml:"channel"`}

type Channel struct { Title string `xml:"title"` Description string `xml:"description"` Items []Item `xml:"item"`}

type Item struct { Title string `xml:"title"` Link string `xml:"link"` Description string `xml:"description"`}

func main() { data := `<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0"> <channel> <title>Example Feed</title> <description>A sample RSS feed</description> <item> <title>First Post</title> <link>https://example.com/1</link> <description>This is the first post.</description> </item> </channel> </rss>`

var rss RSS err := xml.Unmarshal([]byte(data), &rss) if err != nil { panic(err) }

fmt.Printf("القناة: %s", rss.Channel.Title) fmt.Printf("الوصف: %s", rss.Channel.Description) for _, item := range rss.Channel.Items { fmt.Printf("- %s (%s)", item.Title, item.Link) }}


في هذا المثال، العلامة xml:"rss" تربط الهيكل بالعنصر الجذر، بينما xml:"channel" و xml:"item" تربط بالعناصر المتداخلة. الحقل XMLName اختياري، لكنه يسمح بالحصول على اسم العنصر الجذر.



العمل مع سمات XML



تتم معالجة سمات XML من خلال صيغة خاصة في العلامة: xml:"اسم_العلامة,attr". إذا كانت السمة موجودة مباشرة في العنصر الجذر، يتم استخدام xml:",attr".



type Person struct {    XMLName xml.Name `xml:"person"`    ID      int      `xml:"id,attr"`    Name    string   `xml:"name"`    Age     int      `xml:"age,attr"`}

func main() { xmlData := `<person id="123" age="30"><name>Alice</name></person>` var p Person xml.Unmarshal([]byte(xmlData), &p) fmt.Printf("ID: %d, Name: %s, Age: %d", p.ID, p.Name, p.Age) // الإخراج: ID: 123, Name: Alice, Age: 30}


توليد (تسلسل) XML



لإنشاء XML من هيكل، يتم استخدام الدالة xml.Marshal() أو xml.MarshalIndent() للإخراج المنسق. تستخدم الحزمة تلقائيًا علامات الهياكل لتوليد أسماء العناصر والسمات الصحيحة.



type Book struct {    XMLName xml.Name `xml:"book"`    Title   string                    

توصيات