在Go语言中解析JSON

4

我是Go的新手,正在构建一个Web API,用于在我的Android应用程序中使用来自RDW的数据。然而,我在Go中解析JSON时遇到了问题,而在Java中我可以轻松使用类似于jsonObject.getString("AreaId")的方法。在Go中似乎无法这样做。

我正在尝试解析以下JSON以将其保存在MySQL数据库中:

{
  'd': {
    'results': [
      {
        '__metadata': {
          'id': 'https://api.datamarket.azure.com/Data.ashx/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY(1)',
          'uri': 'https://api.datamarket.azure.com/Data.ashx/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY(1)',
          'type': 'opendata.rdw.StatischParkeren.Open.Data.AREAGEOMETRY'
        },
        'AREAGEOMETRY_ID': 1,
        'AreaManagerId': '34',
        'AreaId': 'ALMBUITEN',
        'EndDateArea': null,
        'StartDateArea': '/Date(1330560000000)/',
        'AreaGeometryTxt': 'POLYGON ((5.2736760005354881 52.391216600313783, 5.2752534225583076 52.392331821843982, 5.2771425843238831 52.391448376700282, 5.2795117920336709 52.392518069183787, 5.2794937640428543 52.392529543489218, 5.2795250192284584 52.392524041235447, 5.2795117920336709 52.392518069183787, 5.27959094196558 52.392467692494392, 5.28429589420557 52.394528595730662, 5.2830820381641388 52.3958012573421, 5.2826158106327057 52.396464187651873, 5.28216527402401 52.396755328401923, 5.2811877280473709 52.396325327456, 5.27938649058342 52.395481485873461, 5.2793451324105263 52.395514352247119, 5.2788525596261024 52.395813956856728, 5.278492659330368 52.39611235447228, 5.2776647135615349 52.396820867434144, 5.2777034044265747 52.396853528916836, 5.2768759876489639 52.397581102326512, 5.274177111685276 52.396415254101157, 5.2741994857788086 52.396424867212772, 5.2686141580343246 52.394008679315448, 5.26860549300909 52.394005045294762, 5.2691666409373283 52.39350445382297, 5.2705547362565994 52.392721636220813, 5.2723518460904533 52.392156438032842, 5.2723518460989 52.39215643890202, 5.272359311580658 52.392154090106487, 5.2723518460904533 52.392156438032842, 5.2723498195409775 52.391947904601693, 5.273051455616951 52.391403153538704, 5.2736760005354881 52.391216600313783))',
        'AreaGeometryGml': '<Polygon xmlns="http://www.opengis.net/gml"><exterior><LinearRing><posList>5.2736760005354881 52.391216600313783 5.2752534225583076 52.392331821843982 5.2771425843238831 52.391448376700282 5.2795117920336709 52.392518069183787 5.2794937640428543 52.392529543489218 5.2795250192284584 52.392524041235447 5.2795117920336709 52.392518069183787 5.27959094196558 52.392467692494392 5.28429589420557 52.394528595730662 5.2830820381641388 52.3958012573421 5.2826158106327057 52.396464187651873 5.28216527402401 52.396755328401923 5.2811877280473709 52.396325327456 5.27938649058342 52.395481485873461 5.2793451324105263 52.395514352247119 5.2788525596261024 52.395813956856728 5.278492659330368 52.39611235447228 5.2776647135615349 52.396820867434144 5.2777034044265747 52.396853528916836 5.2768759876489639 52.397581102326512 5.274177111685276 52.396415254101157 5.2741994857788086 52.396424867212772 5.2686141580343246 52.394008679315448 5.26860549300909 52.394005045294762 5.2691666409373283 52.39350445382297 5.2705547362565994 52.392721636220813 5.2723518460904533 52.392156438032842 5.2723518460989 52.39215643890202 5.272359311580658 52.392154090106487 5.2723518460904533 52.392156438032842 5.2723498195409775 52.391947904601693 5.273051455616951 52.391403153538704 5.2736760005354881 52.391216600313783</posList></LinearRing></exterior></Polygon>'
      },
      {
        '__metadata': {
          'id': 'https://api.datamarket.azure.com/Data.ashx/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY(2)',
          'uri': 'https://api.datamarket.azure.com/Data.ashx/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY(2)',
          'type': 'opendata.rdw.StatischParkeren.Open.Data.AREAGEOMETRY'
        },
        'AREAGEOMETRY_ID': 2,
        'AreaManagerId': '34',
        'AreaId': 'ALMTEGELZ',
        'EndDateArea': null,
        'StartDateArea': '/Date(1330560000000)/',
        'AreaGeometryTxt': 'POLYGON ((5.216308925 52.370733155, 5.216800447 52.370804276, 5.216837124 52.370755791, 5.217178542 52.370807152, 5.217373999 52.370322534, 5.217353484 52.370319431, 5.217371539 52.370274734, 5.216664547 52.370167441, 5.216571837 52.370396589, 5.216451509 52.370380301, 5.216308925 52.370733155))',
        'AreaGeometryGml': '<Polygon xmlns="http://www.opengis.net/gml"><exterior><LinearRing><posList>5.216308925 52.370733155 5.216800447 52.370804276 5.216837124 52.370755791 5.217178542 52.370807152 5.217373999 52.370322534 5.217353484 52.370319431 5.217371539 52.370274734 5.216664547 52.370167441 5.216571837 52.370396589 5.216451509 52.370380301 5.216308925 52.370733155</posList></LinearRing></exterior></Polygon>'
      },
 ],
    '__next': 'https://api.datamarket.azure.com/Data.ashx/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY?$skiptoken=100'
  }
}

这是我的Go代码:

type Data struct {
    Next string
    Results Result
}

type Result struct {
    Results []AreaGeometry
}

type AreaGeometry struct {
    AREAGEOMETRY_ID int32
    AreaManagerId int64
    AreaId string
    EndDateArea string
    StartDateArea string
    AreaGeometryTxt string
}

// Synchronizes the AreaGeometry in our MySQL database with the AreaGeometry in the database from the RDW
func retrieveData() {
    resp, err := http.Get("https://api.datamarket.azure.com/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY?$format=json")
    if err != nil {
        panic(err.Error()) // TODO: proper error handling
    }
    body, err := ioutil.ReadAll(resp.Body)
    var d Data
    json.Unmarshal(body, &d)
    fmt.Println("Next: " + d.Next)
}

然而,在反序列化后,d.Next 返回一个空字符串。我做错了什么?在 Go 中如何处理这种情况?


1
在你能够的时候,一定要始终检查错误!err = json.Unmarshal(body, &d) 并打印 err,这将告诉你出了什么问题。 - julienc
嗨,我已经将它改为 err = json.Unmarshal(body, &d),然而在执行后 err = nil。而 fmt.Print(d) 的输出是:{ {[]}}。 - Rik
好的,这次问题肯定来自其他地方,但我向您保证,无论如何检查错误总是更好的选择 ;) - julienc
1个回答

6

您需要使用JSON注释(在文档中称为结构“标记”)来告诉它JSON中字段的名称:

type Data struct {
    Next string `json:"__next"` //Field appears in JSON as key "__next".
    Results Result `json:"results"`
}

我相信Go会自动处理resultsResults的区别,但如果你想将返回的数据转换为小写,仍然需要使用注释。

你的Results Result是不正确的- Results不是Result类型的对象,而是一个AreaGeometry数组,所以它应该长这样:

type Data struct {
    Next string  `json:"__next"` //Field appears in JSON as key "__next".
    Results []AreaGeometry
}

此外,您需要为JSON中的D对象编写一个封装器:
type D struct {
    D Data `json:"d"`
}


func main() {
    body := jsonString //too long to put here, but in the playground. 
    var d D
    err := json.Unmarshal([]byte(body), &d)
    if (err != nil) {
       fmt.Println(err)
    }
    fmt.Println("Next: " + d.D.Next)

}

http://play.golang.org/p/yK-zNxEMvy


3
对于那些查找文档的人来说,这些注释被称为结构体“标签”。 - JimB
@JimB 谢谢!我不知道它们叫什么,我已经更新了答案以反映这一点。 - dave
@dave,他复制粘贴的JSON示例无效,但我手动检查了源代码,一切正常。 - OneOfOne
1
@OneOfOne 我甚至没有想到要这样做,以为需要认证或其他什么东西,但现在看看URL,这样做很聪明。 - dave
谢谢,现在它已经可以工作了。顺便说一下,抱歉提供了错误的示例。 - Rik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接