There's a struct:
type S struct {
Value string `xml:"value,attr"`
}
I want to encode the struct to an XML file. However, I want the attribute name of Value
to be different in each file:
s1 := S{
Value: "One"
}
should encode to:
<S value="One"></S>
and
s2 := S{
Value: "Two"
}
should encode to:
<S category="Two"></S>
So, I need either to change the XML element name somehow, or change the tag on the field. Is this possible?
I checked reflect
(https://golang.org/pkg/reflect/#Value.FieldByName), but since FieldByName
returns a value type and there are no Set
methods, I don't think it's possible to use reflection.
(I don't know why did the other person delete their answer, but here's mine.)
You can either use a combination of ,attr
and ,omitempty
type S struct {
Value string `xml:"value,attr,omitempty"`
Category string `xml:"category,attr,omitempty"`
}
(playground: http://play.golang.org/p/C9tRlA80RV) or create a custom xml.MarshalerAttr
type S struct {
Value Val `xml:",attr"`
}
type Val struct{ string }
func (v Val) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
if v.string == "One" {
return xml.Attr{Name: xml.Name{Local: "value"}, Value: v.string}, nil
}
return xml.Attr{Name: xml.Name{Local: "category"}, Value: v.string}, nil
}
(playground: http://play.golang.org/p/a1Wd2gonb_).
The first approach is easier but less flexible, and also makes the struct bigger. The second approach is slightly more complex, but also more robust and flexible.