简体   繁体   中英

Go: XML API returns oddly encoded string

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>}

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.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM