Einführung in die XML-Verarbeitung mit Go
Die Sprache Go (Golang) bietet eine leistungsstarke und elegante Möglichkeit zur Arbeit mit XML über das Standardpaket encoding/xml. Dieses Paket implementiert eine einfache Schnittstelle zum Lesen (Parsen) und Schreiben (Serialisieren) von XML-Dokumenten unter Verwendung von Annotationen für Strukturen (Struct-Tags). Im Gegensatz zu vielen anderen Sprachen erfordert Go keine separaten DOM- oder SAX-Parser – es reicht aus, die Datenstruktur zu beschreiben, und das Paket ordnet die XML-Tags automatisch den Feldern zu.
In diesem Artikel werden wir die wichtigsten Funktionen des Pakets encoding/xml im Detail behandeln, vom grundlegenden Parsing bis hin zu fortgeschrittenen Techniken: Umgang mit Attributen, Namespaces, Streaming großer Dateien und XML-Generierung. Wir werden auch beliebte Drittanbieter-Bibliotheken betrachten, die in spezifischen Szenarien nützlich sein können.
Grundlagen: XML in Go-Strukturen parsen
Die gebräuchlichste Methode zur Arbeit mit XML in Go ist die Deserialisierung (Unmarshal) von XML-Daten in Strukturinstanzen. Dazu wird die Funktion xml.Unmarshal() verwendet. Das Hauptmerkmal ist die Verwendung von xml:"..."-Tags in der Felddeklaration der Struktur.
Einfaches Beispiel: Parsen eines RSS-Feeds
package main
import ( "encoding/xml" "fmt")
// Struktur für ein RSS-Elementtype 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("Kanal: %s", rss.Channel.Title) fmt.Printf("Beschreibung: %s", rss.Channel.Description) for _, item := range rss.Channel.Items { fmt.Printf("- %s (%s)", item.Title, item.Link) }}In diesem Beispiel verknüpft das Tag xml:"rss" die Struktur mit dem Wurzelelement, und xml:"channel", xml:"item" mit den verschachtelten Elementen. Das Feld XMLName ist optional, ermöglicht aber den Zugriff auf den Namen des Wurzelelements.
Arbeiten mit XML-Attributen
XML-Attribute werden über eine spezielle Syntax im Tag verarbeitet: xml:"tagname,attr". Wenn sich das Attribut direkt im Wurzelelement befindet, wird xml:",attr" verwendet.
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, Alter: %d", p.ID, p.Name, p.Age) // Ausgabe: ID: 123, Name: Alice, Alter: 30}Generierung (Serialisierung) von XML
Zum Erstellen von XML aus einer Struktur wird die Funktion xml.Marshal() oder xml.MarshalIndent() für formatierte Ausgabe verwendet. Das Paket nutzt automatisch die Struktur-Tags, um korrekte Element- und Attributnamen zu generieren.
type Book struct { XMLName xml.Name `xml:"book"` Title string