2

Unmarshalling attributes from the current XML element into an anonymous struct works:

package main

import (
    "encoding/xml"
    "fmt"
)

type Attrs struct {
    Attr1 int `xml:"attr1,attr"`
    Attr2 int `xml:"attr2,attr"`
}
type Element struct {
    Attrs
}

func main() {
    data := `<element attr1="1" attr2="2"></element>`
    v := Element{}
    err := xml.Unmarshal([]byte(data), &v)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    fmt.Printf("%#v\n", v)
}

This prints main.Element{Attrs:main.Attrs{Attr1:1, Attr2:2}} as expected.

If the anonymous struct member is given a name, v.Attr1 and v.Attr2 are not unmarshalled.

type Element struct {
    AttrGroup Attrs
}

What's the correct tag to use on the struct member in this case?

Edit: Playground version

1
  • 1
    I believe it is correct - attributes are expected to be fields, if you stash them into a substruct, there're no longer on the same level hence the result. The question is why would you not use embedding as you had? Commented Apr 17, 2013 at 17:31

1 Answer 1

1

Why not just do this? I don't see what the named struct buys you other than complexity.

(Playground)

package main

import (
    "encoding/xml"
    "fmt"
)

type Element struct {
    Attr1 int `xml:"attr1,attr"`
    Attr2 int `xml:"attr2,attr"`
}

func main() {
    data := `<element attr1="1" attr2="2"></element>`
    v := Element{}
    err := xml.Unmarshal([]byte(data), &v)
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    fmt.Printf("%#v\n", v)
}

Which prints

main.Element{Attr1:1, Attr2:2}
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, this is what I did. Really the problem is the markup (that I can't change) is badly structured, and I thought that the flexibility in Go's XML unmarshalling was for fixing the impedance mismatch. The named struct buys you the ability to keep two related attributes together. Imagine the XML was <line x0="1" y0="1" x1="2" y1="2"/> but you wanted to parse it into two type Point { x int; y int } structures, for instance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.