xmlgostructxml-encoding

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


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"`
    ST
}

Solution

  • This

    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)
    

    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.