Go:解组 JSON 嵌套数组 objects

Go: Unmarshal JSON nested array of objects

我知道你可以 unmarshal arbitrary JSON into a map[string]interface{} value,虽然这行得通,但我的 JSON 响应始终是明确且一致的,为了简单起见,我更愿意将其解组为嵌套结构。

这是 JSON 响应的示例,缩写为:

{
  (...)
  "results": [
    {
      "section": "N.Y. / Region",
      "subsection": "",
      "title": "Christie Spins His Version of Security Record on Trail",
      "abstract": "An examination of Gov. Chris Christie’s record as New Jersey’s top federal prosecutor shows that he has, at times, overstated the significance of the terrorism prosecutions he oversaw.",
      "url": "http://www.nytimes.com/2015/12/27/nyregion/Christie-markets-himself-as-protector-to-gain-in-polls.html",
      "byline": "By ALEXANDER BURNS and CHARLIE SAVAGE",
      "item_type": "Article",
      "updated_date": "2015-12-26T18:04:19-5:00",
      (...)
      "multimedia": [
        {
          "url": "http://static01.nyt.com/images/2015/12/27/nyregion/27CHRISTIE1/27CHRISTIE1-thumbStandard.jpg",
          "format": "Standard Thumbnail",
          "height": 75,
          "width": 75,
          "type": "image",
          "subtype": "photo",
          "caption": "Gov. Chris Christie of New Jersey spoke about the Sept. 11, 2001, attacks at a Republican conference last month.",
          "copyright": "Stephen Crowley/The New York Times"
        }
        (...)
      ]
    }
  ]
}

我试过的

我尝试使用 JSONutils 来自动创建结构并最终得到这个(在删除我不想要的字段之后):

package main

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

type PoliticsJson struct {
    Results []struct {
        Multimedia []struct {
            URL string `json:"url"`
        } `json:"multimedia"`
        Title string `json:"title"`
    } `json:"results"`
}

func retrieveData() []byte {
    url := "http://api.nytimes.com/svc/topstories/v1/politics.json?MYAPIKEY"
    resp, err := http.Get(url)
    if err != nil {
        fmt.Println(err)
    }
    defer resp.Body.Close()
    body, err2 := ioutil.ReadAll(resp.Body)
    if err2 != nil {
        fmt.Println(err2)
    }
    return body
}


func main() {
    var p PoliticsJson

    err := json.Unmarshal(retrieveData(), &p)
    if err != nil {
        panic(err)
    }
    fmt.Println(p.Results[0].Title)
}

我基本上只想打印出多媒体数组中最后一个 object 的标题和 URL。 (我只是想让它工作,所以请原谅错误处理。)

这是我得到的错误:panic: json: cannot unmarshal string into Go value of type []struct { URL string "json:\"url\"" }

问题显然出在 Multimedia 结构上。令我困惑的是,这个错误似乎表明它被解释为一个字符串,但我将结构更改为此以确保:

type PoliticsJson struct {
    Results []struct {
        Multimedia string `json:"multimedia"`
        Title      string `json:"title"`
    } `json:"results"`
}

我得到了 panic: json: cannot unmarshal array into Go value of type string,这表明它 被解释为 JSON.

中的数组

同样,我基本上只想打印出多媒体数组中最后一个 object 的标题和 URL。

尝试使用您的政治Json 和示例 Json 字符串能够解析以获得标题和 URL。

我尝试通过将 URL 更改为 static02 来为多媒体添加一个条目,并且能够同时打印 URL。

这里是 link PlayGround 同样的: http://play.golang.org/p/rAJfkD1i7n

编辑

发现问题,它的发生是因为,在 2 个结果中,多媒体是字符串,即 "multimedia":"" 检查第 975 行和 1319 行。由于数组是预期的,json 失败,因为发现字符串转换这到 "multimedia":[].