Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Trying to use Golang encoding/xml to encode a struct to xml a structure with an alternating repeating pattern

Ask Question

I'm trying to create an xml file with the following ordering using the encoding/xml package and i have defined structs for the static subelement and transition subelement, now the problem is i need to to have this in a repeating format so i created another struct to hold slices of both static and transition structs but the result is the static elements all appear before the transition element but i need them to alternate in order. This is the structure i want:

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

but this is what i get:

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

Any help as to how i could do it. These are the structs i have created:

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"`
                Just to be clear, do you have any control of the XML structure or does it have to be as you specify? Go XML encoding is not designed to preserve order. You might have to write your own encoder. (But I wouldn't be surprised if someone has already done this and put it on Github.)
– Andrew W. Phillips
                May 5, 2020 at 1:53
                If you need an order, you need to model your data structure accordingly. If a static and a transition belong to each other, you should wrap them accordingly, in the already existing ST for example. to further preserve the order of the process wrapper, I'd suggest adding an attribute to ST denoting the order. Then, you can sort the ST elements by that tag on parsing.
– Markus W Mahlberg
                May 5, 2020 at 12:09
    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)

should have your covered (playground).

Note that in order to obtain a properly serialized — in the sense of following one after another in a specified order — list of elements, you have to use a data structure which reflects this; a Go slice suits best in this simple case.

In complicated cases it's possible to make your custom type implement the encoding/xml.Marshaler interface and use a lower-level encoding/xml facilities to encode individual emenets in any order you wish.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.