Go:Unmarshal JSON嵌套的对象数组

时间:2015-12-28 08:12:04

标签: json go unmarshalling

我知道您可以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)
}

我基本上只想打印出多媒体数组中最后一个对象的标题和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中的数组。

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

1 个答案:

答案 0 :(得分:3)

尝试使用您的PoliticsJson和Sample Json字符串能够解析以获取标题和URL。

我尝试通过将网址更改为static02并为两个网址打印来为多媒体添加一个条目。

以下是与PlayGround相同的链接: http://play.golang.org/p/rAJfkD1i7n

修改

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