[英]How to Unmarshall key-less JSON array in Golang correctly?
I have JSON data which looks like this: 我有如下所示的JSON数据:
[
{
"globalTradeID": 64201000,
"tradeID": 549285,
"date": "2016-11-11 23:51:58",
"type": "buy",
"rate": "10.33999779",
"amount": "0.02176472",
"total": "0.22504715"
},
{
"globalTradeID": 64200631,
"tradeID": 549284,
"date": "2016-11-11 23:48:39",
"type": "buy",
"rate": "10.33999822",
"amount": "0.18211700",
"total": "1.88308945"
}...
]
I've tried to unmarshall this JSON by defining a type: 我试图通过定义类型来解组此JSON:
type TradeHistoryResponse []TradeHistoryInfo
type TradeHistoryInfo struct {
GlobalTradeID int64 `json:"globalTradeID"`
TradeID int64 `json:"tradeID"`
Date string `json:"date"`
Type string `json:"type"`
Rate float64 `json:"rate,string"`
Amount float64 `json:"amount,string"`
Total float64 `json:"total,string"`
}
And then pulling the JSON data as so: 然后像这样拉JSON数据:
//Read response
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("[Poloniex] (doRequest) Failed to parse response for query to %s! (%s)", reqURL, err.Error())
}
//Convert JSON to struct
var THR TradeHistoryResponse
err = json.Unmarshal(body, &THR)
if err != nil {
return nil, fmt.Errorf("[Poloniex] (doRequest) Failed to convert response into JSON for query to %s! (%s)", reqURL, err.Error())
}
I get the following error: 我收到以下错误:
(json: cannot unmarshal object into Go value of type poloniex.TradeHistoryResponse)
My best guess why the Unmarshall doesn't work is because the array is key-less? 我最好的猜测是为什么Unmarshall不起作用是因为数组没有密钥?
Would love to have some clarification on the matter on how I might best get this working. 希望就如何最好地解决此问题进行澄清。
I didn't think unmarhsalling an array in a JSON like you intended actually works but to the props of encoding/json it does. 我不认为像您打算的那样在JSON中解组一个数组实际上是可行的,但是对于编码/ json的支持却确实如此。 Example code: package main 示例代码:package main
import (
"encoding/json"
"fmt"
"log"
)
var mjs string = "[" +
"{" +
`"globalTradeID": 64201000,
"tradeID": 549285,
"date": "2016-11-11 23:51:58",
"type": "buy",
"rate": "10.33999779",
"amount": "0.02176472",
"total": "0.22504715"
},
{
"globalTradeID": 64200631,
"tradeID": 549284,
"date": "2016-11-11 23:48:39",
"type": "buy",
"rate": "10.33999822",
"amount": "0.18211700",
"total": "1.88308945"
}
]`
type TradeHistoryResponse []TradeHistoryInfo
type TradeHistoryInfo struct {
GlobalTradeID int64 `json:"globalTradeID"`
TradeID int64 `json:"tradeID"`
Date string `json:"date"`
Type string `json:"type"`
Rate float64 `json:"rate,string"`
Amount float64 `json:"amount,string"`
Total float64 `json:"total,string"`
}
func main() {
//Convert JSON to struct
var THR TradeHistoryResponse
err := json.Unmarshal([]byte(mjs), &THR)
if err != nil {
log.Fatal(err)
}
for _, v := range THR {
fmt.Printf("%+v", v)
fmt.Printf("\n")
}
}
This prints out all the values as expected. 这将按预期打印所有值。 So it doesn't have a problem converting the json values to float/int either (which would have been my second guess). 因此将json值转换为float / int也不会有问题(这是我的第二个猜测)。
Are you sure you aren't modifying the Body in any way ? 您确定没有以任何方式修改Body吗? And that the example you give cover all edge cases ? 您提供的示例涵盖了所有极端情况吗?
Could you add: 您能否添加:
fmt.Println(string(body))
to the second error block and log the error it give here. 到第二个错误块并在此处记录它给出的错误。
Also what version of go are you using ? 另外,您使用的是哪个版本的go? I wouldn't exclude the possibility of encoding/json to have changed between versions. 我不会排除在版本之间更改encoding / json的可能性。 In the end, if this is indeed the case the easy fix would be taking your response as a string, removing all whitespaces and splitting at "}'{" as in: 最后,如果确实如此,那么简单的解决方法就是将您的响应作为字符串,删除所有空格并在“}'{”处进行拆分,如下所示:
fmtBody := strings.Replace(string(body), "\n", "", -1)
fmtBody = strings.Replace(string(fmtBody), "\w", "", -1)
fmtBody = strings.Replace(string(fmtBody), "[", "", -1)
fmtBody = strings.Replace(string(fmtBody), "]", "", -1)
var goArrOfYourJsonsObj []String = strings.Split(fmtBody, "},{")
for k, _ := range goArrOfYourJsonsObj {
goArrOfYourJsonsObj[k] += "}"
}
And now you have your JSON objects neatly separated into a go array of types String which, can be used in Unmarshall as []byte(val). 现在,您已经将JSON对象整齐地分成了一个String类型的go数组,可以在Unmarshall中将其用作[] byte(val)。
TradeHistoryResponse is a type no a variable, you have to create a var of type TradeHistoryResponse, like this: TradeHistoryResponse是没有变量的类型,您必须创建一个TradeHistoryResponse类型的变量,如下所示:
var th TradeHistoryResponse
//Convert JSON to struct
err = json.Unmarshal(body, &th)
// ...
fmt.Printf("%+v\n", th)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.