Reputation:
I try to create multiple xml's that are almost similar, but the element nametag is variating a bit:
<ELEM3_VARIANT_A></ELEM3_VARIANT_A>
and
<ELEM3_VARIANT_B></ELEM3_VARIANT_B>
How can I handle this without the need of a separate struct for each variant? The xml name can be dynamically with
XMLName: xml.Name{Local: "XMLName"},
but how to change the element names (xml nametags like <ELEM2>) ?
<XMLName>
<ELEM1>hello</ELEM1>
<ELEM2></ELEM2>
<ELEM3_VARIANT_A></ELEM3_VARIANT_A>
<ELEM4></ELEM4>
</XMLName>
<XMLName>
<ELEM1>hello</ELEM1>
<ELEM2></ELEM2>
<ELEM3_VARIANT_B></ELEM3_VARIANT_B>
<ELEM4></ELEM4>
</XMLName>
Code example: https://play.golang.org/p/-4JsZa4kbF3
package main
import (
"encoding/xml"
"fmt"
)
type VariantA struct {
XMLName xml.Name
E1 string `xml:"ELEM1"`
E2 string `xml:"ELEM2"`
E3 string `xml:"ELEM3_VARIANT_A"`
E4 string `xml:"ELEM4"`
}
type VariantB struct {
XMLName xml.Name
E1 string `xml:"ELEM1"`
E2 string `xml:"ELEM2"`
E3 string `xml:"ELEM3_VARIANT_B"`
E4 string `xml:"ELEM4"`
}
func test(v interface{}) {
buf, err := xml.MarshalIndent(v, "", " ")
if err != nil {
fmt.Println("error:", err)
} else {
fmt.Println(string(buf))
}
}
func main() {
test(VariantA {
XMLName: xml.Name{Local: "XMLName"},
E1: "hello",
})
test(VariantB {
XMLName: xml.Name{Local: "XMLName"},
E1: "hello",
})
}
Upvotes: 3
Views: 133
Reputation: 38233
Use a custom type that implements the xml.Marshaler
interface.
type VarElem struct {
Name string
Value string
}
func (v VarElem) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
start.Name.Local += v.Name // <- change name of element
return e.EncodeElement(v.Value, start)
}
https://play.golang.org/p/K0BoSOmLbI4
Upvotes: 2