2016-11-16 32 views
0

我有一個看起來像這樣JSON數據:如何在Golang中正確解組無關鍵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" 
    }... 
] 

我試圖通過定義一個類型來解讀這個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"` 
} 

再拉拉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()) 
    } 

我收到以下錯誤:

(json: cannot unmarshal object into Go value of type poloniex.TradeHistoryResponse) 

我最好的猜測爲什麼Unmarshall不起作用是因爲數組無關鍵?

希望對此事做一些澄清,說明如何最好地實現這一目標。

+4

我不確定你的意思是「數組無關鍵」,或者是什麼問題。您的示例代碼有效:https://play.golang.org/p/zbybX0tnRB – JimB

+2

@ nik-kunkel您的示例代碼正常工作,請看一下https://play.golang.org/p/743MBHL3Y4。我最好的主意是你的身體不正確。大概你從身體讀到的不是那個數據。 – sadlil

+1

@JimB和Nik是正確的,也許你應該嘗試寫入標準輸出/文件你正在檢索的身體,並檢查數組中的所有元素是否與你試圖解碼到的類型一致。 –

回答

1

我沒想到的JSON unmarhsalling數組像你預期的實際工作但是它的編碼/ json的道具。示例代碼: 包主

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

此打印出所有的值按預期方式。因此,將json值轉換爲float/int也沒有問題(這可能是我的第二次猜測)。

你確定你沒有以任何方式修改身體嗎?那你給出的例子覆蓋了所有的邊界情況?

您可以加入:

fmt.Println(string(body)) 

第二錯誤塊並記錄它給這裏的錯誤。

你還在用什麼版本去?我不排除encoding/json在版本之間改變的可能性。最後,如果這確實是這樣的簡單的辦法是採取作爲一個字符串您的回覆,刪除所有的空格,並在分裂「}「{」,如:

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] += "}" 
} 

現在你有你的JSON對象整齊地分成一個類型爲String的數組,可以在Unmarshall中用作[] byte(val)。

+0

你的理論正確,你的身體沒有包含正確的數據。我已經實現了一種方法來捕獲服務器返回錯誤,但它似乎並沒有工作。進一步審查後,似乎服務器返回錯誤,因爲URL參數未被正確編碼。 –

0

TradeHistoryResponse是一個類型沒有一個變量,你必須創建類型TradeHistoryResponse的變種,如:

var th TradeHistoryResponse 

//Convert JSON to struct 
err = json.Unmarshal(body, &th) 
// ... 

fmt.Printf("%+v\n", th) 
+0

這實際上是我在創建這篇文章時犯的一個錯誤,爲了儘量減少我必須發佈的代碼量。在Unmarshall函數中,第二個參數實際上是TradeHistoryResponse的變量。 請注意,我編輯了原文以反映這一點。 –