Trabalho com XML em Go (Golang): guia completo com exemplos
Go (Golang) oferece suporte nativo para trabalhar com XML através do pacote encoding/xml. Este pacote fornece ferramentas poderosas para parsing (leitura), geração (escrita) e serialização de dados no formato XML. Diferentemente do JSON, o XML exige uma estrutura mais rígida e suporte a namespaces, o que torna o encoding/xml especialmente flexível.
Neste artigo, abordaremos detalhadamente como trabalhar com XML em Go: desde o unmarshalling básico (conversão de XML para structs Go) até a criação de documentos XML complexos com atributos e namespaces.
Fundamentos: structs e tags XML
Para mapear elementos XML para campos de structs Go, são usadas tags especiais xml. Elas definem o nome do elemento, atributos e comportamento durante a serialização.
type Person struct { XMLName xml.Name `xml:"person"` ID int `xml:"id,attr"` Name string `xml:"name"` Age int `xml:"age"` Email string `xml:"email,omitempty"` Addresses []Address `xml:"address"`}
type Address struct { City string `xml:"city"` Street string `xml:"street"` ZipCode string `xml:"zip"`}xml:"person"— nome do elemento raiz.xml:"id,attr"— o campo se torna um atributo do elemento.xml:"email,omitempty"— o campo é omitido se estiver vazio.xml:"address"— o array será serializado como vários elementos aninhados.
Parsing de XML: Unmarshalling
A função xml.Unmarshal converte bytes XML em uma struct Go. Vejamos um exemplo com nosso tipo Person:
package main
import ( "encoding/xml" "fmt")
func main() { xmlData := `<person id="123"> <name>Иван Петров</name> <age>30</age> <email>ivan@example.com</email> <address> <city>Москва</city> <street>Тверская, 1</street> <zip>101000</zip> </address></person>`
var p Person err := xml.Unmarshal([]byte(xmlData), &p) if err != nil { fmt.Printf("Erro de parsing: %v", err) return }
fmt.Printf("ID: %d", p.ID) fmt.Printf("Nome: %s", p.Name) fmt.Printf("Idade: %d", p.Age) fmt.Printf("Cidade: %s", p.Addresses[0].City)}Saída do programa:
ID: 123Nome: Иван ПетровIdade: 30Cidade: МоскваGeração de XML: Marshalling
Para criar XML a partir de uma struct, usa-se xml.Marshal ou xml.MarshalIndent (com indentação).
func main() { p := Person{ ID: 456, Name: "Анна Смирнова", Age: 25, Email: "anna@example.com", Addresses: []Address{ {City: "Санкт-Петербург", Street: "Невский, 10", ZipCode: "191186"}, }, }
output, err := xml.MarshalIndent(p, "", " ") if err != nil { fmt.Printf("Erro de serialização: %v", err) return }
fmt.Println(string(output))}Resultado:
<person id="456"> <name>Анна Смирнова</name> <age>25</age> <email>anna@example.com</email> <address> <city>Санкт-Петербург</city> <street>Невский, 10</street> <zip>191186</zip> </address></person>Trabalho com namespaces
Namespaces XML são tratados através do campo XMLName com o atributo xmlns.
type Document struct { XMLName xml.Name `xml