douren8379 2016-11-16 01:09
浏览 217
已采纳

如何在Golang中正确解组无键JSON数组?

I have JSON data which looks like this:

[
  {
    "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:

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:

    //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?

Would love to have some clarification on the matter on how I might best get this working.

  • 写回答

2条回答 默认 最新

  • donglei7152 2016-11-16 06:16
    关注

    I didn't think unmarhsalling an array in a JSON like you intended actually works but to the props of encoding/json it does. Example code: 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("
    ")
      }
    }
    

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

    Are you sure you aren't modifying the Body in any way ? 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 ? I wouldn't exclude the possibility of encoding/json to have changed between versions. 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), "
    ", "", -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).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应