在Go中解组以数组开头的JSON时出错。

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

Error unmarshalling JSON in Go that starts with an Array

问题

这是我的代码

package main

import (
    "encoding/json"
    "log"
)

type Data struct {
    Page          int
    Pages         int
    PerPage       string
    Total         int
    CountriesList []Country
}
type Country struct {
    Id  string
    Iso string
}

func main() {
    body := []byte(`[
    {
        "page": 1,
        "pages": 6,
        "per_page": "50",
        "total": 256
    },
    [
        {
            "id": "ABW",
            "iso2Code": "AW"}]]`)

    items := make([]Data, 10)

    if err := json.Unmarshal(body, &items); err != nil {
        log.Fatalf("error %v", err)
    }
}

我试图解析一些JSON并得到以下错误:
错误:无法将数组解析为类型为main.Data的Go值

英文:

This is my code

package main

import (
	"encoding/json"
	"log"
)

type Data struct {
	Page          int
	Pages         int
	PerPage       string
	Total         int
	CountriesList []Country
}
type Country struct {
	Id  string
	Iso string
}

func main() {
	body := []byte(`[
    {
        "page": 1,
        "pages": 6,
        "per_page": "50",
        "total": 256
    },
    [
        {
            "id": "ABW",
            "iso2Code": "AW"}]]`)

	items := make([]Data, 10)

	if err := json.Unmarshal(body, &items); err != nil {
		log.Fatalf("error %v", err)
	}
}

I'm try to unmarshall some JSON and getting the following error:
error json: cannot unmarshal array into Go value of type main.Data

答案1

得分: 2

package main

import (
"encoding/json"
"fmt"
"log"
)

type Data struct {
Page int
Pages int
PerPage string json:"per_page, string"
Total int
}
type Country struct {
Id string
Iso2Code string
}

type DataCountry struct {
Data Data
CountryList []Country
}

func main() {
body := []byte([ { "page": 1, "pages": 6, "per_page": "50", "total": 256 }, [ { "id": "ABW", "iso2Code": "AW"}] ])

raw := make([]json.RawMessage, 10)
if err := json.Unmarshal(body, &raw); err != nil {
    log.Fatalf("error %v", err)
}

sdc := make([]DataCountry, 0)
for i := 0; i < len(raw); i += 2 {
    dc := DataCountry{}

    data := Data{}
    if err := json.Unmarshal(raw[i], &data); err != nil {
        fmt.Println("error %v", err)
    } else {
        dc.Data = data
    }

    var countries []Country
    if err := json.Unmarshal(raw[i+1], &countries); err != nil {
        fmt.Println("error %v", err)
    } else {
        dc.CountryList = countries
    }

    sdc = append(sdc, dc)
}
fmt.Printf("%v\n", sdc)

}

英文:

When reading the question, I assumed that there could be multiple Data + list of Country pairs. Here's the solution I ended up with:

package main

import (
    &quot;encoding/json&quot;
    &quot;fmt&quot;
    &quot;log&quot;
)

type Data struct {
    Page    int
    Pages   int
    PerPage string `json:&quot;per_page, string&quot;`
    Total   int
}
type Country struct {
    Id       string
    Iso2Code string
}

type DataCountry struct {
    Data        Data
    CountryList []Country
}

func main() {
    body := []byte(`[
    {
        &quot;page&quot;: 1,
        &quot;pages&quot;: 6,
        &quot;per_page&quot;: &quot;50&quot;,
        &quot;total&quot;: 256
    },
    [
        {
            &quot;id&quot;: &quot;ABW&quot;,
            &quot;iso2Code&quot;: &quot;AW&quot;}]
]`)

    raw := make([]json.RawMessage, 10)
    if err := json.Unmarshal(body, &amp;raw); err != nil {
        log.Fatalf(&quot;error %v&quot;, err)
    }

    sdc := make([]DataCountry, 0)
    for i := 0; i &lt; len(raw); i += 2 {
        dc := DataCountry{}

        data := Data{}
        if err := json.Unmarshal(raw[i], &amp;data); err != nil {
            fmt.Println(&quot;error %v&quot;, err)
        } else {
            dc.Data = data
        }

        var countries []Country
        if err := json.Unmarshal(raw[i+1], &amp;countries); err != nil {
            fmt.Println(&quot;error %v&quot;, err)
        } else {
            dc.CountryList = countries
        }

        sdc = append(sdc, dc)
    }
    fmt.Printf(&quot;%v\n&quot;, sdc)
}

I found the blog post "Using go to unmarshal json lists with multiple types" very useful for understanding several different options for dealing parsing JSON lists.

答案2

得分: 1

[]main.Data{main.Data{Page:1, Pages:6, Per_Page:"50", Total:256, CountriesList:[]main.Country{main.Country{Id:"ABW", Iso2Code:"AW"}}}}

英文:
package main

import (
        &quot;encoding/json&quot;
        &quot;fmt&quot;
        &quot;log&quot;
)

type Data struct {
        Page          int
        Pages         int
        Per_Page      string
        Total         int
        CountriesList []Country
}
type Country struct {
        Id       string
        Iso2Code string
}

func main() {
        body := []byte(`
        [
                {
                        &quot;page&quot;: 1,
                        &quot;pages&quot;: 6,
                        &quot;per_page&quot;: &quot;50&quot;,
                        &quot;total&quot;: 256,
                        &quot;countrieslist&quot;: [
                                {
                                    &quot;id&quot;: &quot;ABW&quot;,
                                    &quot;iso2Code&quot;: &quot;AW&quot;
                                }
                        ]
                }
        ]
`)

        items := make([]Data, 10)

        if err := json.Unmarshal(body, &amp;items); err != nil {
                log.Fatalf(&quot;error %v&quot;, err)
        }

        fmt.Printf(&quot;%#v\n&quot;, items)
}

Playground


Output:

[]main.Data{main.Data{Page:1, Pages:6, Per_Page:&quot;50&quot;, Total:256, CountriesList:[]main.Country{main.Country{Id:&quot;ABW&quot;, Iso2Code:&quot;AW&quot;}}}}

答案3

得分: 1

package main

import (
"encoding/json"
"fmt"
"log"
)

type T1 struct {
Page, Pages, Total int
PerPage int json:"per_page,string"
}

type T2 struct {
ID string
ISO2Code string
}

func main() {
body := []byte([ { "page": 1, "pages": 6, "per_page": "50", "total": 256 }, [ { "id": "ABW", "iso2Code": "AW" }, { "id": "AFG", "iso2Code": "AF" } ] ])

t1 := T1{}
t2 := []T2{}

if err := json.Unmarshal(body, &[]interface{}{&t1, &t2}); err != nil {
    log.Fatalf("error %v", err)
}

fmt.Printf("%#v  %#v", t1, t2)
for k, v := range t2 {
    fmt.Printf("%v %v\n", k, v.ID)
}

}

英文:

I got some help from #go-nuts on IRC:

package main


import (
  &quot;encoding/json&quot;
  &quot;fmt&quot;
  &quot;log&quot;
)

type T1 struct {
  Page, Pages, Total int
  PerPage            int `json:&quot;per_page,string&quot;`
}

type T2 struct {
  ID       string
  ISO2Code string
}

func main() {
  body := []byte(`
    [
      {
        &quot;page&quot;: 1,
        &quot;pages&quot;: 6,
        &quot;per_page&quot;: &quot;50&quot;,
        &quot;total&quot;: 256
      },
      [
        {
          &quot;id&quot;: &quot;ABW&quot;,
          &quot;iso2Code&quot;: &quot;AW&quot;
        },
        {
          &quot;id&quot;: &quot;AFG&quot;,
          &quot;iso2Code&quot;: &quot;AF&quot;
        }
      ]
    ]
  `)

  t1 := T1{}
  t2 := []T2{}

  if err := json.Unmarshal(body, &amp;[]interface{}{&amp;t1, &amp;t2}); err != nil {
    log.Fatalf(&quot;error %v&quot;, err)
  }

  fmt.Printf(&quot;%#v  %#v&quot;, t1, t2)
  for k, v := range t2 {
    fmt.Printf(&quot;%v %v\n&quot;,k, v.ID)
  }
}

huangapple
  • 本文由 发表于 2013年7月29日 21:53:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/17925925.html
匿名

发表评论

匿名网友

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

确定