Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Parse XML Data In A Golang Application

TwitterFacebookRedditLinkedInHacker News

While I don’t see a lot of it anymore, XML is still a common data format that people use. I prefer JSON, but I don’t always have a say in how I receive data. Some time ago I wrote a few tutorials on which include parsing XML data with Node.js, parsing XML data with Java, and parsing XML data with PHP. If you’ve been keeping up, I’ve been doing a lot of development with the Go programming language which is why I think it would be a great idea to go over XML in Golang.

Of the various programming languages, I think XML is the easiest to work with in the Go programming language. We’re going to see how to take XML data and unmarshal it into a custom structure. We’re also going to see how to take JSON data and convert it into XML.

The cool thing about Golang is that we don’t need any external packages when working with JSON or XML. Everything is already built into the language.

For this project, take the following XML:

<data>
    <person>
        <firstname>Nic</firstname>
        <lastname>Raboy</lastname>
        <address>
            <city>San Francisco</city>
            <state>CA</state>
        </address>
    </person>
    <person>
        <firstname>Maria</firstname>
        <lastname>Raboy</lastname>
    </person>
</data>

The goal here is to work with an array of XML nodes as well as nested XML data. To be clear, we want to work with complex XML data.

Create and open a main.go file which will contain all of the code for this example. This file will look like the following:

package main

import (
    "encoding/json"
    "encoding/xml"
    "fmt"
)

type Data struct {
    XMLName    xml.Name `xml:"data" json:"-"`
    PersonList []Person `xml:"person" json:"people"`
}

type Person struct {
    XMLName   xml.Name `xml:"person" json:"-"`
    Firstname string   `xml:"firstname" json:"firstname"`
    Lastname  string   `xml:"lastname" json:"lastname"`
    Address   *Address `xml:"address" json:"address,omitempty"`
}

type Address struct {
    City  string `xml:"city" json:"city,omitempty"`
    State string `xml:"state" json:"state,omitempty"`
}

func main() {
    rawXmlData := "<data><person><firstname>Nic</firstname><lastname>Raboy</lastname><address><city>San Francisco</city><state>CA</state></address></person><person><firstname>Maria</firstname><lastname>Raboy</lastname></person></data>"
    var data Data
    xml.Unmarshal([]byte(rawXmlData), &data)
    jsonData, _ := json.Marshal(data)
    fmt.Println(string(jsonData))
}

In the above example we have three custom structures to represent each layer of our XML data.

The root node of our XML data can be represented by the Data structure. In this node we know that we’ll have several <person> nodes which can be represented by a slice of Person structure. The <person> node will have address information which can be represented by the Address structure.

Probably the most interesting part of this is the annotations for each structure property. The annotations are how we map each XML tag to a property and each property to a JSON property. Any annotation with a hyphen will be ignored.

When we run the application, it will parse the XML and print it out as JSON that looks like the following:

{
    "people": [
        {
            "firstname": "Nic",
            "lastname": "Raboy",
            "address": {
                "city": "San Francisco",
                "state": "CA"
            }
        },
        {
            "firstname": "Maria",
            "lastname": "Raboy"
        }
    ]
}

The great thing about this setup is that we can go in the opposite direction as well. If we wanted to take JSON data and output XML, we totally could.

Take the following revised main function found in the main.go file:

func main() {
    rawJsonData := "{\"people\": [{\"firstname\": \"Nic\", \"lastname\": \"Raboy\"}]}"
    var data Data
    json.Unmarshal([]byte(rawJsonData), &data)
    xmlData, _ := xml.Marshal(data)
    fmt.Println(string(xmlData))
}

If all went well, the output should be XML as defined by our custom structures.

Conclusion

You just saw how to work with XML formatted data in a Golang application. You can consume XML data and convert it into a custom structure or JSON data and you can even take JSON data and convert it into XML data. I wrote about doing the same in Java, Node.js, and PHP, but accomplishing this in the Go programming language is a lot easier.

A video version of this article can be seen below.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.