Multiple-types decoder in golang

拜拜、爱过 提交于 2019-12-05 12:51:25

You can achieve this by defining a new type that conforms to the xml.Unmarshaler interface. So rather than making Lines a []string, declare a new type with an appropriate UnmarshalXML method. For instance:

type Lines []string

func (l *Lines) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    var content string
    if err := d.DecodeElement(&content, &start); err != nil {
        return err
    }
    *l = strings.Split(content, "\n")
    return nil
}

You can see a full example here: http://play.golang.org/p/3SBu3bOGjR

If you want to support encoding this type too, you can implement the MarshalXML method in a similar fashion (construct the string content you want and pass that to the encoder).

Here is a spelled out example of what CSE is suggesting:

type Document struct {
    Title    string `xml:"title"`
    LineData string `xml:"lines"`
}

func (d *Document)Lines() []string {
    return strings.Split(d.LineData, '\n')
}

This is similar to what net/http Request does: read the data into a struct, and then provide accessors to interpret that struct.

If you really don't want to do that, then another approach that I have used is to create two structs. Read the raw data into the first and then use that to construct the second.

If you are planning on shipping this out as JSON or some other wire format, the second struct could just be a map.

func (d *Document) Map() map[string]interface{} {
    m := make(map[string]interface{})
    m["lines"] = strings.Split(d.LineData, '\n')
    m["title"] = d.Title
    return m
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!