user13418553
user13418553

Reputation:

How to get xml nametag variants without separate struct

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

Answers (1)

mkopriva
mkopriva

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

Related Questions