1 回答

TA貢獻(xiàn)1802條經(jīng)驗 獲得超5個贊
該響應(yīng)不是有效的 XML 文檔,因此您無法按原樣一步或不進(jìn)行修改/“修飾”對其進(jìn)行解碼。
以下解決方案用作body
未讀響應(yīng)正文流:Response.Body
。
1. 解碼為一系列XML文檔
然而,它可以被視為一系列XML文檔,因此您可以用來xml.Decoder
逐一解碼它們。
例如:
var res result
dec := xml.NewDecoder(body)
var err error
decField := func(v interface{}) {
? ? if err == nil {
? ? ? ? err = dec.Decode(v)
? ? }
}
decField(&res.Status)
decField(&res.Statusmsg)
decField(&res.Vmstat)
decField(&res.Hostname)
decField(&res.Ipaddress)
if err != nil {
? ? fmt.Println(err)
}
fmt.Printf("%+v\n", res)
輸出(在Go Playground上嘗試):
{Status:success?Statusmsg:online?Vmstat:online?Hostname:kvm-vps2?Ipaddress:123.456.789.99}
是的,逐場解碼很不方便。
2. 讀取正文并用根標(biāo)簽包裝
另一種選擇是用標(biāo)簽包裝它,使其成為有效的 XML 文檔:
buf := &bytes.Buffer{}
buf.WriteString("<root>")
if _, err := io.Copy(buf, body); err != nil {
? ? panic(err)
}
buf.WriteString("</root>")
var res result
if err := xml.Unmarshal(buf.Bytes(), &res); err != nil {
? ? panic(err)
}
fmt.Printf("%+v\n", res)
這輸出相同。在Go Playground上嘗試一下。
是的,上述解決方案必須首先將正文讀入內(nèi)存。
3. 包裝主體流而不將其讀入內(nèi)存
不過,我們可以避免閱讀并將正文保留在內(nèi)存中。我們可以構(gòu)建一個閱讀器,在閱讀時首先提供開始包裝標(biāo)簽,然后提供“原始”主體,最后提供結(jié)束標(biāo)簽。為此,我們可以使用io.MultiReader()
:
r := io.MultiReader(
? ? strings.NewReader("<root>"),
? ? body,
? ? strings.NewReader("</root>"),
)
var res result
if err := xml.NewDecoder(r).Decode(&res); err != nil {
? ? panic(err)
}
fmt.Printf("%+v\n", res)
這再次輸出相同的結(jié)果。在Go Playground上試試這個。
- 1 回答
- 0 關(guān)注
- 155 瀏覽
添加回答
舉報