【问题标题】:Golang: how to read data inside nested JSON object? [duplicate]Golang:如何读取嵌套 JSON 对象中的数据? [复制]
【发布时间】:2020-10-03 16:48:57
【问题描述】:

我是Golang的新手,最近写了以下代码sn-p:

resp, _ := http.Get("https://api.vagalume.com.br/search.art?q=Aerosmith&limit=5")
obj := map[string]interface{}{}
responseData, _ := ioutil.ReadAll(resp.Body)
json.Unmarshal([]byte(string(responseData)), &obj)

网址:https://api.vagalume.com.br/search.art?q=Aerosmith&limit=5 应该检索嵌套的 JSON。

{
  "response":{
     "numFound":1,
     "start":0,
     "numFoundExact":true,
     "docs":[
      {
        "id":"b3ade68b3g6f86eda3",
        "url":"/aerosmith/",
        "band":"Aerosmith",
        "fmRadios":["...", "..."]
      }]
  },
  "highlighting":{
    "b3ade68b3g6f86eda3":{}}}

而那一行:

obj["response"]

是有效的,但是行:

obj["response"]["docs"]

不编译。

如何访问“response”->“docs”中的内容?

编辑:答案Unmarshaling nested JSON objects 对我不好,因为我想找到一种方法来读取结构未知的 JSON 对象。

【问题讨论】:

  • 没有。因为我不知道 JSON 的结构。
  • 如果您不知道 JSON 的外观,您可能希望使用一个为您解析 json 的库。例如:github.com/tidwall/gjson。你可以叫它gjson.Get(json_string, "response.docs")
  • @pikaynu 谢谢。 tidwall/gjson 就是答案。

标签: go


【解决方案1】:

例如,您可以这样做:

package main

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

type myData struct {
    Response struct {
        NumFound      int  `json:"numFound"`
        Start         int  `json:"start"`
        NumFoundExact bool `json:"numFoundExact"`
        Docs          []struct {
            ID       string   `json:"id"`
            URL      string   `json:"url"`
            Band     string   `json:"band"`
            FmRadios []string `json:"fmRadios"`
        } `json:"docs"`
    } `json:"response"`
    Highlighting struct {
        B3Ade68B3G6F86Eda3 struct {
        } `json:"b3ade68b3g6f86eda3"`
    } `json:"highlighting"`
}


func main() {
    resp, _ := http.Get("https://api.vagalume.com.br/search.art?q=Aerosmith&limit=5")
    responseData, _ := ioutil.ReadAll(resp.Body)
    d := myData{}
    err := json.Unmarshal(responseData, &d)
    if err != nil {
        panic(err)
    }
    fmt.Println(d.Response.Docs)
}

输出:

[{b3ade68b3g6f86eda3 /aerosmith/ Aerosmith [14634980201914128847|acustico 1464201608479108132|rock 1464720376206867533|rock-ballads 14647977281792658143|rock-classico 1470155219129532|romantico 1475867272151401|rock-das-raizes-ao-progressivo 1479752883943544|heavy-metal 1506975770142563|pop-rock 1508779923321353|para-viajar 1514919045178434|hits-anos-90 1521216096352408|hard-rock 1522179349368851|monday 1522261529679510|depre 1528233925925603|dia-dos-namorados 1534365009290224|favoritas-do-vagalume]}]

编辑:

或者,如建议的那样,如果您不知道 JSON 的结构,您可以使用这个:

package main

import (
    "github.com/tidwall/gjson"
    "io/ioutil"
    "net/http"
)


func main() {
    resp, _ := http.Get("https://api.vagalume.com.br/search.art?q=Aerosmith&limit=5")
    responseData, _ := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()

    value := gjson.GetBytes(responseData, "response.docs")
    println(value.String())
}

输出:

[
      {
        "id":"b3ade68b3g6f86eda3",
        "url":"/aerosmith/",
        "band":"Aerosmith",
        "fmRadios":["14634980201914128847|acustico",
          "1464201608479108132|rock",
          "1464720376206867533|rock-ballads",
          "14647977281792658143|rock-classico",
          "1470155219129532|romantico",
          "1475867272151401|rock-das-raizes-ao-progressivo",
          "1479752883943544|heavy-metal",
          "1506975770142563|pop-rock",
          "1508779923321353|para-viajar",
          "1514919045178434|hits-anos-90",
          "1521216096352408|hard-rock",
          "1522179349368851|monday",
          "1522261529679510|depre",
          "1528233925925603|dia-dos-namorados",
          "1534365009290224|favoritas-do-vagalume"]}]

【讨论】:

    【解决方案2】:

    如果您不想(或不能)使用合适类型的结构,则需要类型转换。

    response, ok := obj["response"].(map[string]interface{})
    if !ok {
        ... return an error
    }
    docs := response["docs"]
    

    obj 的类型是map[string]interface{},所以任何obj[<field>] 的类型都是interface{}。如果该字段的值是 JSON 对象,则它也将是 map[string]interface{} 类型,如 https://golang.org/pkg/encoding/json/#Unmarshal 中所定义。您可以在该文档中查看您可能对其他字段感兴趣的其他类型。

    【讨论】:

      猜你喜欢
      • 2018-05-29
      • 1970-01-01
      • 2017-09-29
      • 1970-01-01
      • 1970-01-01
      • 2019-10-22
      • 1970-01-01
      • 2015-06-10
      • 1970-01-01
      相关资源
      最近更新 更多