如何提取嵌套的JSON数据?

时间:2019-03-23 00:50:50

标签: go

我在data.json中具有以下内容:

{  
    "table":"orderBook10",
    "action":"update",
    "data":[  
       {  
          "symbol":"XBTUSD",
          "bids":[  
             [  
                3996,
                49137
             ],
             [  
                3995.5,
                116
             ],
             [  
                3995,
                165
             ],
             [  
                3994.5,
                166
             ],
             [  
                3994,
                237
             ],
             [  
                3993.5,
                45
             ],
             [  
                3992,
                20064
             ],
             [  
                3991.5,
                209
             ],
             [  
                3991,
                134
             ],
             [  
                3990.5,
                2948
             ]
          ],
          "timestamp":"2019-03-23T00:34:40.505Z",
          "asks":[  
             [  
                3996.5,
                975
             ],
             [  
                3997,
                289
             ],
             [  
                3997.5,
                334
             ],
             [  
                3998,
                419
             ],
             [  
                3998.5,
                423
             ],
             [  
                3999,
                930
             ],
             [  
                3999.5,
                547
             ],
             [  
                4000,
                538
             ],
             [  
                4000.5,
                703
             ],
             [  
                4001,
                997
             ]
          ]
       }
    ]
 }

到目前为止,我的程序可以提取data字段:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
)

func main() {

    dat, err := ioutil.ReadFile("./data.json")
    if err != nil {
        panic(err)
    }

    var ob map[string]interface{}
    if err := json.Unmarshal(dat, &ob); err != nil {
        panic(err)
    }
    fmt.Println(ob["data"])
}

我现在想提取嵌套的“请求”字段。

我尝试过:

data := ob["data"]
asks := data["asks"].([][]int)

但这会导致我无法解读的语法错误。

如何将嵌套的asks字段分配给变量?

3 个答案:

答案 0 :(得分:1)

您的ob["data"] JSON结构如下:

([]interface {}) {
  (map[string]interface {}) {
    (string) "": (string) "",
    (string) "": ([]interface {}) {
      ([]interface {}) {
        (float64),
        (float64) 
      }
    },
    (string) "": (string) "",
    (string) "": ([]interface {}) {
      ([]interface {}) {
        (float64),
        (float64)
      }
    }
  }
}

因此您将需要使用以下内容:

ob["data"].([]interface{})[0].(map[string]interface{})["asks"]

其中:

  • ob["data"]广播到[]interface{}
  • 使用第一个(在您的示例中,也是唯一的)元素[0]
  • 将此元素投射到map[string]interface{},并且
  • 然后提取"asks"

注意: 除非您确定,否则请始终对type assertions使用以下形式t, ok := i.(T)

  

如果我持有T,则t将是基础值,而ok将为真。

     

否则,ok将为假,t将为T类型的零值,并且不会发生恐慌。

答案 1 :(得分:1)

解析JSON的方法可以通过以下方法实现。

步骤1:定义结构

type OuterJson struct {
  Table string `json:"table"`
  Action string `json:"action"`
  DataJson []DataJson `json:"data"`
}

type DataJson struct {
  Symbol string `json:"symbol"`
  Timestamp string `json:"timestamp"`
  BidsJson [][]float64 `json:"bids"`
  AsksJson [][]float64 `json:"asks"`

}

步骤2:声明输入和输出

input := `{"table":"orderBook10","action":"update","data":[{"symbol":"XBTUSD","bids":[[3996,49137],[3995.5,116],[3995,165],[3994.5,166],[3994,237],[3993.5,45],[3992,20064],[3991.5,209],[3991,134],[3990.5,2948]],"timestamp":"2019-03-23T00:34:40.505Z","asks":[[3996.5,975],[3997,289],[3997.5,334],[3998,419],[3998.5,423],[3999,930],[3999.5,547],[4000,538],[4000.5,703],[4001,997]]}]}`
var output OuterJson

步骤3:从给定输入(或解组)中获取输出

json.Unmarshal([]byte(input), &output)

结合所有,您将得到

package main

import (
    "fmt"
    "encoding/json"
)

type OuterJson struct {
  Table string `json:"table"`
  Action string `json:"action"`
  DataJson []DataJson `json:"data"`
}

type DataJson struct {
  Symbol string `json:"symbol"`
  Timestamp string `json:"timestamp"`
  BidsJson [][]float64 `json:"bids"`
  AsksJson [][]float64 `json:"asks"`

}  

func main() {
    fmt.Println("Hello, playground")
    input := `{"table":"orderBook10","action":"update","data":[{"symbol":"XBTUSD","bids":[[3996,49137],[3995.5,116],[3995,165],[3994.5,166],[3994,237],[3993.5,45],[3992,20064],[3991.5,209],[3991,134],[3990.5,2948]],"timestamp":"2019-03-23T00:34:40.505Z","asks":[[3996.5,975],[3997,289],[3997.5,334],[3998,419],[3998.5,423],[3999,930],[3999.5,547],[4000,538],[4000.5,703],[4001,997]]}]}`
    var output OuterJson
    json.Unmarshal([]byte(input), &output)
    fmt.Println(output)     
}

尝试这个link

答案 2 :(得分:0)

您的结构应该是

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
)
type JsonData struct {
    Table  string `json:"table"`
    Action string `json:"action"`
    Data   []struct {
        Symbol    string      `json:"symbol"`
        Bids      [][]int     `json:"bids"`
        Timestamp time.Time   `json:"timestamp"`
        Asks      [][]float64 `json:"asks"`
    } `json:"data"`
}

func main() {
    dat, err := ioutil.ReadFile("./data.json")
    if err != nil {
        panic(err)
    }

    var ob JsonData
    if err := json.Unmarshal([]byte(dat), &ob); err != nil {
        panic(err)
    }
    fmt.Println(ob)
   }

您可以利用以下链接从嵌套的JSON对象生成结构。

https://mholt.github.io/json-to-go/

http://json2struct.mervine.net/