Fred Stock
Fred Stock

Reputation: 11

Parsing XML attributes with GO

I am pretty new to GO and I am having trouble extracting attribute values from XML documents. The code below produces the following output:

application ID:: "" application name:: ""

My assumption is that I am missing something when it comes to how to use tagging and I would really appreciate it if someone could point me in the right direction.

data:=`<?xml version="1.0" encoding="UTF-8"?>
    <applist>
        <app app_id="1234" app_name="abc"/>
    <app app_id="5678" app_name="def"/>
    </applist> `

type App struct {
    app_id   string  `xml:"app_id,attr"`
    app_name string  `xml:"app_name"`
}

type AppList struct {
    XMLName xml.Name `xml:"applist"`
    Apps  []App      `xml:"app"`
}

var portfolio AppList
err := xml.Unmarshal([]byte(data), &portfolio)
if err != nil {
    fmt.Printf("error: %v", err)
    return
}
fmt.Printf("application ID:: %q\n", portfolio.Apps[0].app_id)
fmt.Printf("application name:: %q\n", portfolio.Apps[0].app_name)

Upvotes: 1

Views: 3102

Answers (1)

Will C
Will C

Reputation: 1794

In order to be able to get the elements out you have to have "exported" fields, meaning that app_id and app_name in the App struct should start with a capital letter. In addition, your app_name field is also missing a ,attr in its xml field tag. See below for a working example of your code. I've added comments on the lines that require some changes.

package main

import (
    "fmt"
    "encoding/xml"
)

func main() {
    data:=`
    <?xml version="1.0" encoding="UTF-8"?>
    <applist>
        <app app_id="1234" app_name="abc"/>
        <app app_id="5678" app_name="def"/>
    </applist>
    `

    type App struct {
        App_id   string  `xml:"app_id,attr"`    // notice the capitalized field name here
        App_name string  `xml:"app_name,attr"`  // notice the capitalized field name here and the `xml:"app_name,attr"`
    }

    type AppList struct {
        XMLName xml.Name `xml:"applist"`
        Apps  []App      `xml:"app"`
    }

    var portfolio AppList
    err := xml.Unmarshal([]byte(data), &portfolio)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    fmt.Printf("application ID:: %q\n", portfolio.Apps[0].App_id)       // the corresponding changes here for App
    fmt.Printf("application name:: %q\n", portfolio.Apps[0].App_name)   // the corresponding changes here for App
}

Upvotes: 5

Related Questions