考虑以下结构:
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
答案 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