Read an XML file in Golang

We will show you how to read an XML file in Golang, with a simple XML example with User nodes and basic data such as name, username, password and email. In addition to this data we have a “type” attribute that tells us what kind of user we are storing. The XML file that we will read is as follows:

» More Golang Examples

xml_example.xml

<users>
    <user type="admin">
        <name>Jhon</name>
        <username>jhon</username>
        <password>123321</password>
        <mail>jhon1@test.com</mail>
    </user>
    <user type="query">
        <name>Sophia</name>
        <username>sophia</username>
        <password>111</password>
        <mail>sophia@test.com</mail>
    </user>
</users>

The code to read this specific XML file in Golang is as follows:

package main

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

//geekole.com

type Users struct {
	Users   []User   `xml:"user"`
}
 
type User struct {
	Type    string `xml:"type,attr"`
	Name    string `xml:"name"`
	Username    string `xml:"username"`
	Password    string `xml:"password"`
	Mail    string `xml:"mail"`
}
 
func main() {
	data, _ := ioutil.ReadFile("xml_example.xml")
 
	users := &Users{}
 
	_ = xml.Unmarshal([]byte(data), &users)
 
	fmt.Println("users found: ", len(users.Users))
	for i:= 0; i < len(users.Users); i++  {
		fmt.Println("type: ", users.Users[i].Type)
		fmt.Println("name: ", users.Users[i].Name)
		fmt.Println("username: ", users.Users[i].Username)
		fmt.Println("password: ", users.Users[i].Password)
		fmt.Println("mail: ", users.Users[i].Mail)
	}
}

We briefly explain what we do. First we create two structs with the same node structure as our XML. The root node is the “users” node and we will map it with the “Users” struct as follows:

type Users struct {
	Users   []User   `xml:"user"`
}

We are only storing an array of structs “User”, with the name in the singular and whose definition is the following:

type User struct {
	Type    string `xml:"type,attr"`
	Name    string `xml:"name"`
	Username    string `xml:"username"`
	Password    string `xml:"password"`
	Mail    string `xml:"mail"`
}

One important thing to note is that the attributes of an XML node are explicitly defined as attributes with the keyword “attr” as follows:

Type    string `xml:"type,attr" 

The child nodes within our node of interest as a user, will only carry the ‘xml:name’ plugin with the name of the node that we need to map.

To read the XML in our code, the first thing we do is open the text file with ReadFile and then we create a Users instance in which we will map our data array from the XML with the call to Unmarshal as shown below:

	data, _ := ioutil.ReadFile("xml_example.xml")
 
	users := &Users{}
 
	_ = xml.Unmarshal([]byte(data), &users)

Finally we show the content of our Users array in the console:

        fmt.Println("users found: ", len(users.Users))
	for i:= 0; i < len(users.Users); i++  {
		fmt.Println("type: ", users.Users[i].Type)
		fmt.Println("name: ", users.Users[i].Name)
		fmt.Println("username: ", users.Users[i].Username)
		fmt.Println("password: ", users.Users[i].Password)
		fmt.Println("mail: ", users.Users[i].Mail)
	}
Running the example will give you the following output:

Read an XML file in Golang

As you can see, with this way of reading an XML it is necessary to know in advance the exact structure that you expect to have in the XML.

If you declare variables in your struct that are not in the XML they will simply not be read and will be empty. Reading an XML file in Golang is not complicated, but you must take care that the structure of your XML and your structs are consistent.

See more: https://golang.org/src/encoding/xml/example_test.go