I have this XML structure:
<group id="26659127">
<member ref="292403538"/>
<member ref="298884289"/>
<member ref="261728686"/>
<info k="name" v="omega"/>
<info k="rank" v="16"/>
</group>
I need to convert this XML into this struct:
{
Id: "26659127",
Members: ["26659127", "298884289", "261728686"],
Info: [
{
Key: "name",
Value: "omega"
},
{
Key: "rank",
Value: "16"
}
]
}
I created a struct for parsing XML already:
type Group struct {
Id string `xml:"id,attr"`
Members []string `xml:" "`
Info []Info `xml:"info"`
}
type Info struct {
Key string `xml:"k,attr"`
Value string `xml:"v,attr"`
}
But, as you can see I haven't defined an expression for Members
yet. Actually, I tried putting xml:"member,ref,attr"
and xml:"member:ref,attr"
in here, but it didn't work.
Is there a possibility to solve this issue? If yes, what expression I should use?
Unfortunately there is no way to use the default XML unmarshaler to achieve your goal by using only struct field tags so you'll have to either:
xml.Unmarshaler
by extracting the value of the "ref" attribute from the associated XML element.Here is an example of how you can implement strategy #2 above (Go Playground):
type Group struct {
Id string `xml:"id,attr"`
Members []MemberRef `xml:"member"`
Info []Info `xml:"info"`
}
type MemberRef string
func (m *MemberRef) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
*m = MemberRef(start.Attr[0].Value) // Assume only the "ref" attribute exists.
_, err := d.Token() // Consume and discard the synthetic xml.EndElement.
return err
}
// ...
var group Group
err := xml.Unmarshal([]byte(xmlstr), &group)
if err != nil {
panic(err)
}
fmt.Printf("%#v
", group)
// main.Group{Id:"26659127", Members:[]main.MemberRef{"292403538", "298884289", "261728686"}, Info:...
Note that you can even marshal this struct directly into the example JSON format you listed:
bs, err := json.MarshalIndent(group, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(bs))
// {
// "Id": "26659127",
// "Members": [
// "292403538",
// "298884289",
// "261728686"
// ],
// "Info": [
// ...