上一篇我們學習了怎么發送各種數據類型的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)
}