Skip to content

XML in Go

Go supports XML through the encoding/xml package. It works very similarly to the JSON package but with a few extra struct tag options for attributes and nesting.

1. Marshalling (Go to XML)

package main

import (
    "encoding/xml"
    "fmt"
)

type Plant struct {
    XMLName xml.Name `xml:"plant"`
    ID      int      `xml:"id,attr"` // XML Attribute
    Name    string   `xml:"name"`
    Origin  []string `xml:"origin"`
}

func main() {
    coffee := &Plant{ID: 27, Name: "Coffee"}
    coffee.Origin = []string{"Ethiopia", "Brazil"}

    // Use MarshalIndent for human-readable output
    out, _ := xml.MarshalIndent(coffee, " ", "  ")
    fmt.Println(xml.Header + string(out))
}

Output:

1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
 <plant id="27">
   <name>Coffee</name>
   <origin>Ethiopia</origin>
   <origin>Brazil</origin>
 </plant>

2. Unmarshalling (XML to Go)

1
2
3
4
data := []byte(`<plant id="27"><name>Coffee</name></plant>`)
var p Plant
xml.Unmarshal(data, &p)
fmt.Println(p.Name) // Coffee

3. XML Struct Tags

  • xml:"tag_name": Maps the field to an XML tag.
  • xml:"id,attr": Maps the field to an attribute (e.g., <plant id="1">).
  • xml:"parent>child": Maps to nested tags (e.g., <parent><child>value</child></parent>).
  • xml:",chardata": Maps to the raw text inside a tag.
  • xml:",innerxml": Maps to the raw, unparsed XML inside a tag.

Why use XML?

  1. Legacy Systems: Many older enterprise APIs and configuration files use XML.
  2. Strictness: XML schemas (XSD) allow for very strict data validation.
  3. Namespaces: Good for merging data from different sources without name collisions.