Parsing JSON in Go

huangapple go评论76阅读模式
英文:

Parsing JSON in Go

问题

我是新手学习Go语言,我正在构建一个使用RDW数据的Web API,用于在我的Android应用程序中。然而,我在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
}

// 将我们MySQL数据库中的AreaGeometry与RDW数据库中的AreaGeometry同步
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语言中应该如何处理这个问题?

英文:

I am new to Go, and I am building a web API that uses data from the RDW in my Android Application. However I have trouble parsing JSON in Go, where as in Java I could easily use something like jsonObject.getString(&quot;AreaId&quot;). It does not seem like I can do this in Go.

I am trying to parse the following JSON to save it in a MySQL database:

{
&#39;d&#39;: {
&#39;results&#39;: [
{
&#39;__metadata&#39;: {
&#39;id&#39;: &#39;https://api.datamarket.azure.com/Data.ashx/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY(1)&#39;,
&#39;uri&#39;: &#39;https://api.datamarket.azure.com/Data.ashx/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY(1)&#39;,
&#39;type&#39;: &#39;opendata.rdw.StatischParkeren.Open.Data.AREAGEOMETRY&#39;
},
&#39;AREAGEOMETRY_ID&#39;: 1,
&#39;AreaManagerId&#39;: &#39;34&#39;,
&#39;AreaId&#39;: &#39;ALMBUITEN&#39;,
&#39;EndDateArea&#39;: null,
&#39;StartDateArea&#39;: &#39;/Date(1330560000000)/&#39;,
&#39;AreaGeometryTxt&#39;: &#39;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))&#39;,
&#39;AreaGeometryGml&#39;: &#39;&lt;Polygon xmlns=&quot;http://www.opengis.net/gml&quot;&gt;&lt;exterior&gt;&lt;LinearRing&gt;&lt;posList&gt;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&lt;/posList&gt;&lt;/LinearRing&gt;&lt;/exterior&gt;&lt;/Polygon&gt;&#39;
},
{
&#39;__metadata&#39;: {
&#39;id&#39;: &#39;https://api.datamarket.azure.com/Data.ashx/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY(2)&#39;,
&#39;uri&#39;: &#39;https://api.datamarket.azure.com/Data.ashx/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY(2)&#39;,
&#39;type&#39;: &#39;opendata.rdw.StatischParkeren.Open.Data.AREAGEOMETRY&#39;
},
&#39;AREAGEOMETRY_ID&#39;: 2,
&#39;AreaManagerId&#39;: &#39;34&#39;,
&#39;AreaId&#39;: &#39;ALMTEGELZ&#39;,
&#39;EndDateArea&#39;: null,
&#39;StartDateArea&#39;: &#39;/Date(1330560000000)/&#39;,
&#39;AreaGeometryTxt&#39;: &#39;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))&#39;,
&#39;AreaGeometryGml&#39;: &#39;&lt;Polygon xmlns=&quot;http://www.opengis.net/gml&quot;&gt;&lt;exterior&gt;&lt;LinearRing&gt;&lt;posList&gt;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&lt;/posList&gt;&lt;/LinearRing&gt;&lt;/exterior&gt;&lt;/Polygon&gt;&#39;
},
],
&#39;__next&#39;: &#39;https://api.datamarket.azure.com/Data.ashx/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY?$skiptoken=100&#39;
}
}

This is my code in 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(&quot;https://api.datamarket.azure.com/opendata.rdw/StatischParkeren.Open.Data/v1/AREAGEOMETRY?$format=json&quot;)
if err != nil {
panic(err.Error()) // TODO: proper error handling
}
body, err := ioutil.ReadAll(resp.Body)
var d Data
json.Unmarshal(body, &amp;d)
fmt.Println(&quot;Next: &quot; + d.Next)
}

However, d.Next returns an empty string after unmarshaling. What am I doing wrong? What is the Go way of taking care of this?

答案1

得分: 6

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

type Data struct {
    Next    string  `json:"__next"` //字段在JSON中以键"__next"出现。
    Results Result  `json:"results"`
}

我相信Go会自动处理resultsResults之间的区别,但是如果你要发送数据并希望它是小写的,你仍然需要使用注释。

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

type Data struct {
    Next    string          `json:"__next"` //字段在JSON中以键"__next"出现。
    Results []AreaGeometry `json:"results"`
}

此外,你需要一个包装器来包装JSON中的D对象:

type D struct {
    D Data `json:"d"`
}
func main() {
    body := jsonString //太长了,无法在这里放置,但在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

英文:

You need to use JSON annotations (referred to as struct "tags" in the docs) to let it know what the name of the field is in the JSON:

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

I believe Go automatically takes care of results vs Results, but if you are going to send data back and want it to be lowercase, you still need the annotation.

Your Results Result is incorrect - Results is not an object of type Result, it is an array of AreaGeometry, so it should look like:

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

Also, you need a wrapper for the D object that is in the JSON:

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

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

huangapple
  • 本文由 发表于 2014年8月15日 00:16:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/25312824.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定