On Tue, 11 Oct 2016 10:00:33 -0700 (PDT)
sm...@brillig.org wrote:

[...]
> > > I'm trying to Marshal XML where an element has mixed content: 
> > > https://www.w3.org/TR/REC-xml/#sec-mixed-content 
> > > 
> > > I tried just using []interface{} but if I put in just a string, 
> > > Marshal surrounds each string with the name of the slice: 
[...]
> > Yes.  "\nhello\n" and "\nworld\n" are what is called "character
> > data" in XML parlance.  So if you go with the standard approach to
> > marshaling data to XML -- via a struct type with properly annotated
> > fields -- you should annotate the fields for your character data
> > chunks with the ",chardata" modifiers. 
> >
> > See the docs on encoding/xml.Marshal function for more info. 
[...]
> Sorry, I should have been more clear.  The reason I used a slice was 
> because I need an arbitrary number of elements. So I can't just use a 
> static struct with the chardata tags.

OK, doable with custom marshaler code:

----------------8<----------------
package main

import (
    "encoding/xml"
    "fmt"
    "os"
)

type Elements []interface{}

func (es Elements) MarshalXML(e *xml.Encoder, start xml.StartElement) (err 
error) {
    for _, v := range es {
        if s, ok := v.(string); ok {
            err = e.EncodeToken(xml.CharData([]byte(s)))
            if err != nil {
                break
            }
            continue
        }
        err = e.Encode(v)
        if err != nil {
            break
        }
    }
    return
}

func main() {
    type Root struct {
        XMLName  xml.Name `xml:"root"`
        Elements Elements
    }

    type E1 struct {
        XMLName xml.Name `xml:"element1"`
        Source  string   `xml:",chardata"`
    }

    type E2 struct {
        XMLName xml.Name `xml:"element2"`
        Source  string   `xml:",chardata"`
    }

    var doc = &Root{
        Elements: Elements{
            &E1{Source: "foo"}, "hello",
            &E2{Source: "bar"}, "world"},
    }

    output, err := xml.MarshalIndent(doc, "  ", "    ")
    if err != nil {
        fmt.Printf("error: %v\n", err)
    }

    os.Stdout.Write(output)
}
----------------8<----------------

Playground link: <https://play.golang.org/p/twSkrZIVY9>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to