普通网友 2015-07-01 22:31
浏览 48
已采纳

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

Consider the following struct:

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

Which has the following UnmarshalXML function:

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
}

My problem with this code is these lines:

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{})

My question is how I make the correct use of the xml annotations (,innerxml etc), fields and structs, so I don't have to manually pre-/append the <meta></meta> tags afterwards to get the whole Meta field as a single map.

The full code example is here: http://play.golang.org/p/Q4_tryubO6

展开全部

  • 写回答

1条回答 默认 最新

  • dongzong3053 2015-07-08 07:40
    关注

    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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

悬赏问题

  • ¥15 KeiI中头文件找不到怎么解决
  • ¥15 QT6将音频采样数据转PCM
  • ¥15 本地安装org.Hs.eg.dby一直这样的图片报错如何解决?
  • ¥15 下面三个文件分别是OFDM波形的数据,我的思路公式和我写的成像算法代码,有没有人能帮我改一改,如何解决?
  • ¥15 Ubuntu打开gazebo模型调不出来,如何解决?
  • ¥100 有chang请一位会arm和dsp的朋友解读一个工程
  • ¥50 求代做一个阿里云百炼的小实验
  • ¥15 查询优化:A表100000行,B表2000 行,内存页大小只有20页,运行时3页,设计两个表等值连接的最简单的算法
  • ¥15 led数码显示控制(标签-流程图)
  • ¥20 为什么在复位后出现错误帧