Unmarshaling XML with an attribute on a self-closing tag

1,526 views
Skip to first unread message

indraniel

unread,
Feb 7, 2015, 5:27:56 PM2/7/15
to golan...@googlegroups.com

I’m exploring “encoding/xml”‘s Unmarshal function to get a better understanding of its features.

An Unmarshaling scenario I’ve been looking at is to create a proper golang struct to parse an XML snippet that looks like:

    <ASSEMBLY>
      <COMMON>Build 37</COMMON>
      <STANDARD short_name="GRCh37-lite"/>
    </ASSEMBLY>

I’ve been able to successfully the above XML using two structures, described below ( and in http://play.golang.org/p/RiI422j163 ):

package main

import (
    "encoding/xml"
    "fmt"
)

func main() {

    type Standard struct {
            ShortName string `xml:"short_name,attr"`
    }

    type Assembly struct {
        XMLName xml.Name `xml:"ASSEMBLY"`
        Common string `xml:"COMMON"`
        Std Standard `xml:"STANDARD"`
    }


    var v Assembly

    data := `
        <ASSEMBLY>
          <COMMON>Build 37</COMMON>
          <STANDARD short_name="GRCh37-lite"/>
        </ASSEMBLY>
    `
    err := xml.Unmarshal([]byte(data), &v)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    fmt.Printf("%#v\n", v)
}

However, I’m only interested in parsing just value of the COMMON element and the “short_name” attribute on the STANDARD element.

Is there a way I could elegantly Unmarshal my interesting elements of the XML directly into a single struct like

type Assembly struct {
    XMLName xml.Name  `xml:"ASSEMBLY"`
    Common string
    ShortName string
}

?

Egon

unread,
Feb 7, 2015, 6:15:55 PM2/7/15
to golan...@googlegroups.com
AFAIK, xml package isn't capable of doing that (easily). One possibility would be to use an embedded struct.

    type Assembly struct {
        XMLName xml.Name `xml:"ASSEMBLY"`
        Common string `xml:"COMMON"`
        Std struct {
            ShortName string `xml:"short_name,attr"`
        } `xml:"STANDARD"`
    }

The other version would involve implementing Marshaler/Unmarshaler interfaces, it would allow hiding the second struct inside those methods.

+ Egon

Matt Harden

unread,
Feb 16, 2015, 11:00:15 PM2/16/15
to Egon, golan...@googlegroups.com
Yes, I would go with implementing xml.Unmarshaler. It isn't very hard: http://play.golang.org/p/StN_AQGYkS

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

indraniel

unread,
Feb 17, 2015, 10:00:28 AM2/17/15
to golan...@googlegroups.com, egon...@gmail.com

Many Thanks for providing illustrative examples for both approaches! I was also looking at Francesc Campoy’s recent presentation: JSON, interfaces and go generate. Although it is about JSON, the unmarshaling ideas given in the presentation seem similar to what both of you have suggested for XML unmarshaling.

Reply all
Reply to author
Forward
0 new messages