duandao8607 2018-01-25 21:47
浏览 36
已采纳

具有不同类型或对象继承的数组

I'm programming an xml response API in golang. Following the examples in the xml documentation it's pretty easy to create the xml giving them attributes and more.

The thing is that I need multiple tags under the same name and in different order.

<block>
    <tag1>A Value1</tag1>
    <tag2>B Value1</tag2>
    <tag1>A Value2</tag1>
</block>

By creating a structure like

type Tag1 struct {
    Value string `xml:",chardata"`
}
type Tag2 struct {
    Value string `xml:",chardata"`
}
type Block struct {
    XMLName   xml.Name `xml:"block"`
    Tags1     []Tag1   `xml:"tag1"`
    Tags2     []Tag2   `xml:"tag2"`
}

I achieved this xml:

<block>
    <tag1>A Value1</tag1>
    <tag1>A Value2</tag1>
    <tag2>B Value1</tag2>
</block>

That's due to the array type inside the block definition. What I want, is a way to define that array type as an interface to inherit the two Tag types. Like this

type Block struct {
    XMLName   xml.Name `xml:"block"`
    Tags      []Tags   `xml:"tags"`
}
type (Tags t) Tag1 struct{
    Value string `xml:",chardata"`
}
type (Tags t) Tag2 struct{
    Value string `xml:",chardata"`
}

This way I could define the order of appearance in xml by the order of appending like

a1 := Tag1{"A Value1"}
b1 := Tag2{"B Value1"}
a2 := Tag1{"A Value2"}

arr :=  []Tags{}
arr = append(arr,a1)
arr = append(arr,b1)
arr = append(arr,a2)

v.Tags = arr

I've made some reading and I'm trying to avoid to implement the marshaling function used inside the xml package. Any help is appreciated, thanks.

  • 写回答

1条回答 默认 最新

  • douwo3665 2018-01-25 22:30
    关注

    I solved it differently. I just wasn't looking for the right approach. This question described what I needed. By defining the XMLName xml.Name value in the Tag1 struct, I could define the name of the tag programmatically. And then just include the different Tags value with the old friend []interface{} type.

    type Tag1 struct {
        XMLName xml.Name
        Value   string `xml:",chardata"`
    }
    type Block struct {
        XMLName xml.Name `xml:"block"`
        Tags    []interface{}
    }
    a1 := Tag1{XMLName: xml.Name{Local: "tag1"}, Value: "A Value1"}
    a2 := Tag1{XMLName: xml.Name{Local: "tag1"}, Value: "A Value2"}
    b1 := Tag2{XMLName: xml.Name{Local: "tag2"}, Value: "B Value1"}
    
    v := &Block{}
    v.Tags = []interface{}{a1, b1, a2}
    

    Check this example out to give it a play.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 cad图纸,chx-3六轴码垛机器人
  • ¥15 移动摄像头专网需要解vlan
  • ¥20 access多表提取相同字段数据并合并
  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源
  • ¥15 安卓JNI项目使用lua上的问题
  • ¥20 RL+GNN解决人员排班问题时梯度消失