如何在没有单独结构的情况下获得 xml 名称标签变体

How to get xml nametag variants without separate struct

我尝试创建多个几乎相似的 xml, 但元素名称标签略有不同:

<ELEM3_VARIANT_A></ELEM3_VARIANT_A> 

<ELEM3_VARIANT_B></ELEM3_VARIANT_B>

如何在不需要为每个变体创建单独的结构的情况下处理这个问题? xml 名称可以动态地与

XMLName: xml.Name{Local: "XMLName"},

但是如何更改元素名称(xml 名称标签,如 )?

<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>

代码示例: 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",
    })


}

使用实现 xml.Marshaler 接口的自定义类型。

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