【问题标题】:Trying to use Golang encoding/xml to encode a struct to xml a structure with an alternating repeating pattern尝试使用 Golang encoding/xml 将结构编码为 xml 具有交替重复模式的结构
【发布时间】:2020-05-04 23:29:56
【问题描述】:

我正在尝试使用 encoding/xml 包创建一个具有以下顺序的 xml 文件,并且我已经为静态子元素和转换子元素定义了结构,现在的问题是我需要以重复格式使用它所以我创建了另一个结构来保存静态和过渡结构的切片,但结果是静态元素都出现在过渡元素之前,但我需要它们按顺序交替。 这是我想要的结构:

<background>
    //...
    <static>
        <duration></duration>
        <file></file>
    </static>

    <transition>
        <duration>
        <from></from>
        <to></to>
    </transition>

    <static>
        <duration></duration>
        <file></file>
    </static>

    <transition>
        <duration>
        <from></from>
        <to></to>
    </transition>
    //...
</background>

但这就是我得到的:

<background>
    //...
    <static>
        <duration></duration>
        <file></file>
    </static>
    <static>
        <duration></duration>
        <file></file>
    </static>

    <transition>
        <duration>
        <from></from>
        <to></to>
    </transition>
    <transition>
        <duration>
        <from></from>
        <to></to>
    </transition>
    //...
</background>

关于我如何做到这一点的任何帮助。 这些是我创建的结构:

type Static struct {
Duration int    `xml:"duration"`
File     string `xml:"file"`
}
type Transition struct {
    Duration float64 `xml:"duration"`
    From     string  `xml:"from"`
    To       string  `xml:"to"`
}
type ST struct {
    Static     []Static     `xml:"static"`
    Transition []Transition `xml:"transition"`
}

type Background struct {
    XMLName   xml.Name  `xml:"background"`
    Comment   string    `xml:",comment"`
    ST
}

【问题讨论】:

  • 澄清一下,您对 XML 结构有任何控制权还是 必须 像您指定的那样? Go XML 编码不是为了保持顺序而设计的。您可能必须编写自己的编码器。 (但如果有人已经这样做并将其放在 Github 上,我不会感到惊讶。)
  • 如果你需要一个订单,你需要对你的数据结构进行相应的建模。如果static 和转换属于彼此,您应该相应地包装它们,例如在已经存在的ST 中。为了进一步保留流程包装器的顺序,我建议向ST 添加一个属性来表示顺序。然后,您可以在解析时按该标记对 ST 元素进行排序。

标签: xml go struct xml-encoding


【解决方案1】:

这个

type Static struct {
    XMLName  string `xml:"static"`
    Duration int    `xml:"duration"`
    File     string `xml:"file"`
}

type Transition struct {
    XMLName  string  `xml:"transition"`
    Duration float64 `xml:"duration"`
    From     string  `xml:"from"`
    To       string  `xml:"to"`
}

type Background struct {
    XMLName string `xml:"background"`
    Items   []interface{}
}

bk := Background{
    Items: []interface{}{
        &Static{
            Duration: 11,
            File:     "foo",
        },
        &Transition{
            Duration: 22,
            From:     "aaa",
            To:       "bbb",
        },
        &Static{
            Duration: 33,
            File:     "bar",
        },
        &Transition{
            Duration: 44,
            From:     "xxx",
            To:       "yyy",
        },
    },
}

out, err := xml.Marshal(&bk)

应该覆盖您的 (playground)。

请注意,为了获得一个正确序列化的——即按照指定顺序一个接一个地跟随——元素列表,您必须使用反映这一点的数据结构; Go 切片最适合这种简单的情况。

在复杂的情况下,可以让您的自定义类型实现 encoding/xml.Marshaler 接口,并使用较低级别的 encoding/xml 设施以您希望的任何顺序对各个 emenets 进行编码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 2018-05-01
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    相关资源
    最近更新 更多