1 回答

TA貢獻(xiàn)1872條經(jīng)驗(yàn) 獲得超4個(gè)贊
該響應(yīng)不是有效的 XML 文檔,因此您不能在一個(gè)步驟中按原樣解碼它,也不能不進(jìn)行修改/“裝飾”。
以下解決方案body用作未讀響應(yīng)正文流:Response.Body.
1. 解碼為一系列 XML 文檔
但是,它可以被視為一系列XML 文檔,因此您可以使用xml.Decoder它來逐個(gè)解碼它們。
例如:
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)
這個(gè)輸出(在Go Playground上試試):
{Status:success Statusmsg:online Vmstat:online Hostname:kvm-vps2 Ipaddress:123.456.789.99}
是的,逐場(chǎng)解碼很不方便。
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. 包裹body流而不將其讀入內(nèi)存
不過,我們可以避免閱讀并將正文保存在內(nèi)存中。我們可以構(gòu)建一個(gè)閱讀器,它在閱讀時(shí)首先提供開始包裝標(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)
這再次輸出相同的內(nèi)容。在Go Playground上試試這個(gè)。
- 1 回答
- 0 關(guān)注
- 118 瀏覽
添加回答
舉報(bào)