今天在使用微信支付的时候遇到这样一种情况:支付成功之后微信会发送一个通知过来,这个通知包含xml格式的数据,其中有一个字段是这样的:

coupon_id_n,代金券或立减优惠ID, n , Unknown node type: a 或立减优惠ID,n,代金券或立减优惠ID,n为下标,从0开始编号
func XmlDecode(data string) map[string]string{
   decoder := xml.NewDecoder(strings.NewReader(data))
   result  := make(map[string]string)
   key := ""
   for{
      token, err := decoder.Token() //读取一个标签或者文本内容
      if err==io.EOF{
         fmt.Println("parse Finish")
         return result
      }
      if err!=nil{
         fmt.Println("parse Fail:",err)
         return result
      }
      switch tp := token.(type) {  //读取的TOKEN可以是以下三种类型:StartElement起始标签,EndElement结束标签,CharData文本内容
      case xml.StartElement:
         se := xml.StartElement(tp) //强制类型转换
         if se.Name.Local!="xml"{
            key=se.Name.Local
         }
         if len(se.Attr)!=0{ //读取标签属性
            fmt.Println("Attrs:",se.Attr)
         }
         fmt.Println("SE.NAME.SPACE:",se.Name.Space) //读取命名空间
         fmt.Println("SE.NAME.LOCAL:",se.Name.Local) //读取标签名称
         fmt.Println()
      case xml.EndElement:
         ee := xml.EndElement(tp)
         if ee.Name.Local == "xml"{
            return result
         }
         fmt.Println("EE.NAME.SPACE:",ee.Name.Space)
         fmt.Println("EE.NAME.LOCAL:",ee.Name.Local)
      case xml.CharData: //文本数据,注意一个结束标签和另一个起始标签之间可能有空格
         cd := xml.CharData(tp)
         data := strings.TrimSpace(string(cd))
         if len(data)!=0{
            result[key] = data
            fmt.Println(key,",",data)
         }
      }
   }
}

上面的代码用微信的返回数据作为例子,代码比较简单,流程上就是读取一个TOKEN,判断TOKEN的类型然后把数据填到map里面。