In this example we are going to read an XML file and map it to its struct type. At the end, the result will be printed for the sake of confirmation. One special note, if the XML content is "beautified", the output will contain some special characters such as #xA; (line feed), #x9; (tab) and spaces. If it is "minified", the output should be clean.


XML file (beautified)


<!-- User Bank Account and History -->
<?xml version="1.0" encoding="UTF-8"?>
<user>
<id>1</id>
<first_name>John</first_name>
<middle_name></middle_name>
<last_name>Doe</last_name>
<address>Line 1
Line 2

Line 3

Line 4</address>
<random>
<nickname>Dummy User</nickname>
<favourite_colour>Blue</favourite_colour>
</random>
<accounts>
<account number="11" sort_code="111">
<history>
<transaction time="2020-09-25T20:41:30+01:00">
<operation>Debit</operation>
<amount>1021</amount>
</transaction>
<transaction time="2019-12-31T00:33:10+01:00">
<operation>Credit</operation>
<amount>50</amount>
</transaction>
</history>
</account>
<account number="22" sort_code="222">
<history>
<transaction time="2021-03-11T10:11:10+01:00">
<operation>Credit</operation>
<amount>5000</amount>
</transaction>
</history>
</account>
</accounts>
</user>

Code


package main

import (
"encoding/xml"
"fmt"
"io/ioutil"
"log"
"os"
)

func main() {
// Open file
xmlFile, err := os.Open("input.xml")
if err != nil {
log.Fatalln(err)
}
defer xmlFile.Close()

// Read file
val, err := ioutil.ReadAll(xmlFile)
if err != nil {
log.Fatalln(err)
}

// Map data
var user User
if err := xml.Unmarshal(val, &user); err != nil {
log.Fatalln(err)
}

// Print result (as-is)
dat, err := xml.MarshalIndent(user, "", " ")
if err != nil {
log.Fatalln(err)
}
fmt.Println(string(dat))
}

type User struct {
XMLName xml.Name `xml:"user"`
Text string `xml:",chardata"`
ID string `xml:"id"`
FirstName string `xml:"first_name"`
MiddleName string `xml:"middle_name"`
LastName string `xml:"last_name"`
Address string `xml:"address"`
Random Random `xml:"random"`
Accounts Accounts `xml:"accounts"`
}

type Random struct {
Text string `xml:",chardata"`
Nickname string `xml:"nickname"`
FavouriteColour string `xml:"favourite_colour"`
}

type Accounts struct {
Accounts []Account `xml:"account"`
}

type Account struct {
Text string `xml:",chardata"`
Number string `xml:"number,attr"`
SortCode string `xml:"sort_code,attr"`
History History `xml:"history"`
}

type History struct {
Text string `xml:",chardata"`
Transaction []Transaction `xml:"transaction"`
}

type Transaction struct {
Text string `xml:",chardata"`
Time string `xml:"time,attr"`
Operation string `xml:"operation"`
Amount string `xml:"amount"`
}