上一篇我们学习了怎么发送各种数据类型的http请求,这一篇我们来介绍怎么来解析接口返回的XML的数据。

解析接口返回数据

定义结构体

resp
<?xml version="1.0" encoding="utf-8"?>
<ResponseWithResponseInfo>
  <code>00</code>
  <message>SUCCESS</message>
  <describe>成功</describe>
  <resultInfo>
    <uniqueNumber>201808161133401673324075025000035</uniqueNumber>
  </resultInfo>
</ResponseWithResponseInfo>

要解析这个数据,首先我们要定义一个与之树状结构一致的结构体:

type XMLresp struct {
	ResponseWithResponseInfo xml.Name `xml:"ResponseWithResponseInfo"`
	Code                        int      `xml:"code"`
	Message                     string   `xml:"message"`
	Describe                    string   `xml:"describe"`
	ResultInfo                  struct {
		XMLName      xml.Name `xml:"resultInfo"`
		UniqueNumber string   `xml:"uniqueNumber"`
	}
}

这里要注意xml.Name 这个tag,它表示后面的数据的父元素是什么,如果没有填写这个信息,在数据解析的时候可能会获取不到数据。

解析函数:

xml.Unmarshal
// XMLUnpack xml数据解析
func XMLUnpack(respbody string) (Prase []interface{}, errs error) {
	temp := []byte(respbody)
	v := XMLresp{}
	errs = xml.Unmarshal(temp, &v)
	Prase = []interface{}{v.Code, v.Message, v.Describe, v.ResultInfo.UniqueNumber}
	if errs != nil {
		return
	}
	return
}

测试

func main() {
	data, _ := XMLUnpack(resp)
	fmt.Println(data)
}

输出:

bingo@Mac unpackData$ go run paraseXML.go
[0 SUCCESS 成功 201808161133401673324075025000035]

优化

XMLUnpack

那么有没有办法能解决这个问题呢,答案当然是有的,下面我们一起来解决这个问题。

不知道大家还记不记得我么之前一起学习过的method语法,它的优点是可以让不同作用的函数使用同一个函数名称(属性),可以完成面向对象语言特有的继承和重写操作,如果忘记了可以看看之前的学习笔记【Golang】基础09 通过method完成面向对象

method
// XMLUnpack 短信网关xml返回结果解析
func (smsresp *XMLresp) XMLUnpack(respbody string) (Prase []interface{}, errs error) {
	temp := []byte(respbody)
	v := SmsXMLresp{}
	errs = xml.Unmarshal(temp, &v)
	Prase = []interface{}{v.Code, v.Message, v.Describe, v.ResultInfo.UniqueNumber}
	if errs != nil {
		return
	}
	return
}
*XMLresp
func main() {
	var p XMLresp
	data, _ := p.XMLUnpack(resp)
	fmt.Println(data)
}