英文:
Go: XML API returns oddly encoded string
问题
我正在尝试解析来自API的XML响应,当调用fmt.Println
并传递响应主体时,我得到一个奇怪的字符串:
&{0xc8200e6140 {0 0} false <nil> 0xc2030 0xc1fd0}
我已确认我可以使用curl
访问API并获得预期的XML响应。(使用Postman Chrome扩展发送GET
请求也会得到相同的响应。)这是一个编码问题吗?
以下是相关的代码:
type Album struct {
Title string `xml:"album>name"`
Artist string `xml:"album>artist>name"`
PlayCount uint64 `xml:"album>playcount"`
}
const lastFMAPIKey string = "<My api key>"
const APIURL string = "http://ws.audioscrobbler.com/2.0/"
func perror(err error) {
if err != nil {
panic(err)
}
}
func getListeningInfo(url string) []byte {
resp, err := http.Get(url)
perror(err)
defer resp.Body.Close()
// 这是打印上述字符串的那一行
fmt.Println(resp.Body)
body, err2 := ioutil.ReadAll(resp.Body)
perror(err2)
return body
}
func main() {
url := APIURL + "?method=user.getTopAlbums&user=iamnicholascox&period=1month&limit=1&api_key=" + lastFMAPIKey
album := Album{}
err := xml.Unmarshal(getListeningInfo(url), &album)
perror(err)
fmt.Printf(album.Artist)
}
作为参考,打印resp
而不仅仅是resp.Body
会得到以下结果:
{200 OK 200 HTTP/1.1 1 1 map[Ntcoent-Length:[871]
Connection:[keep-alive] Access-Control-Max-Age:[86400]
Cache-Control:[private] Date:[Thu, 03 Dec 2015 05:16:34 GMT]
Content-Type:[text/xml; charset=UTF-8]
Access-Control-Request-Headers:[Origin, X-Atmosphere-tracking-id, X-Atmosphere-Framework, X-Cache-Date,
Content-Type, X-Atmosphere-Transport, *]
Access-Control-Allow-Methods:[POST, GET, OPTIONS]
Access-Control-Allow-Origin:[*]
Server:[openresty/1.7.7.2]]
0xc8200f6040 -1 [] false map[] 0xc8200b8000 <nil>}
请注意,我只翻译了你提供的代码和相关的输出,不包括其他内容。
英文:
I'm trying to parse the XML response from an API, and when call fmt.Println
and pass the response body, I get a weird string:
&{0xc8200e6140 {0 0} false <nil> 0xc2030 0xc1fd0}
I've confirmed that I can curl
the API and get XML as expected. (I also get the same response sending a GET
request with the Postman Chrome extension.) Is this an encoding issue?
Here's the relevant code:
type Album struct {
Title string `xml:"album>name"`
Artist string `xml:"album>artist>name"`
PlayCount uint64 `xml:"album>playcount"`
}
const lastFMAPIKey string = "<My api key>"
const APIURL string = "http://ws.audioscrobbler.com/2.0/"
func perror(err error) {
if err != nil {
panic(err)
}
}
func getListeningInfo(url string) []byte {
resp, err := http.Get(url)
perror(err)
defer resp.Body.Close()
// this is the line that prints the string above
fmt.Println(resp.Body)
body, err2 := ioutil.ReadAll(resp.Body)
perror(err2)
return body
}
func main() {
url := APIURL + "?method=user.getTopAlbums&user=iamnicholascox&period=1month&limit=1&api_key=" + lastFMAPIKey
album := Album{}
err := xml.Unmarshal(getListeningInfo(url), &album)
perror(err)
fmt.Printf(album.Artist)
}
For reference, printing out resp
instead of just resp.Body
gives this:
{200 OK 200 HTTP/1.1 1 1 map[Ntcoent-Length:[871]
Connection:[keep-alive] Access-Control-Max-Age:[86400]
Cache-Control:[private] Date:[Thu, 03 Dec 2015 05:16:34 GMT]
Content-Type:[text/xml; charset=UTF-8]
Access-Control-Request-Headers:[Origin, X-Atmosphere-tracking-id, X-Atmosphere-Framework, X-Cache-Date,
Content-Type, X-Atmosphere-Transport, *]
Access-Control-Allow-Methods:[POST, GET, OPTIONS]
Access-Control-Allow-Origin:[*]
Server:[openresty/1.7.7.2]]
0xc8200f6040 -1 [] false map[] 0xc8200b8000 <nil>}
答案1
得分: 2
http.Response的Body是一个io.ReaderCloser。你看到的奇怪输出是作为响应体使用的结构体字段的值。
如果你想要打印出实际的内容,你必须先从Body中读取它。
尝试使用ioutil.ReadAll来实现:
b, err := ioutil.ReadAll(resp.Body) // 这里的b是一个[]byte
if err != nil {
fmt.Println("发生错误:", err)
} else {
fmt.Println(string(b)) // 将[]byte转换为字符串以便打印到屏幕上
}
英文:
The http.Response's Body is an io.ReaderCloser. The odd output you are seeing is the values of the fields of struct used as the response body.
if you want the actual content to print out, you must read it from the Body first.
Try ioutil.ReadAll by doing:
b, err := ioutil.ReadAll(resp.Body) // b is a []byte here
if err != nil {
fmt.Println("Got error:",err)
} else {
fmt.Println(string(b)) // convert []byte to string for printing to the screen.
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论