在自定义UnmarshalXML函数中正确使用XML注释,字段和结构

时间:2015-07-02 06:31:03

标签: go

考虑以下结构:

type MyStruct struct {
    Name string
    Meta map[string]interface{}
}

具有以下UnmarshalXML功能:

func (m *MyStruct) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    var v struct {
        XMLName xml.Name //`xml:"myStruct"`
        Name    string   `xml:"name"`
        Meta    struct {
            Inner []byte `xml:",innerxml"`
        } `xml:"meta"`
    }

    err := d.DecodeElement(&v, &start)
    if err != nil {
        return err
    }

    m.Name = v.Name
    myMap := make(map[string]interface{})

    // ... do the mxj magic here ... -

    temp := v.Meta.Inner

    prefix := "<meta>"
    postfix := "</meta>"
    str := prefix + string(temp) + postfix
    //fmt.Println(str)
    myMxjMap, err := mxj.NewMapXml([]byte(str))
    myMap = myMxjMap

    // fill myMap
    //m.Meta = myMap
    m.Meta = myMap["meta"].(map[string]interface{})
    return nil
}

我对此代码的问题是以下几行:

prefix := "<meta>"
postfix := "</meta>"
str := prefix + string(temp) + postfix
myMxjMap, err := mxj.NewMapXml([]byte(str))
myMap = myMxjMap
//m.Meta = myMap
m.Meta = myMap["meta"].(map[string]interface{})

我的问题是我如何正确使用xml注释(,innerxml等),字段和结构,所以我不必手动预先/附加<meta></meta>标签以获得将整个Meta字段作为单个地图。

完整的代码示例如下:http://play.golang.org/p/Q4_tryubO6

1 个答案:

答案 0 :(得分:5)

xml package doesn't provide a way to unmarshal XML into map[string]interface{} because there is no single way to do it and in some cases it is not possible. A map doesn't preserve order of the elements (that is important in XML) and doesn't allow elements with duplicate keys.

mxj package that you used in your example has some rules how to unmarshal arbitrary XML into Go map. If your requirements do not conflict with these rules you can use mxj package to do all parsing and do not use xml package at all:

// I am skipping error handling here
m, _ := mxj.NewMapXml([]byte(s))
mm := m["myStruct"].(map[string]interface{})
myStruct.Name = mm["name"].(string)
myStruct.Meta = mm["meta"].(map[string]interface{})

Full example: http://play.golang.org/p/AcPUAS0QMj