Golang unmarshall JSON from api.nal.usda.gov/ndb

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

Golang unmarshall JSON from api.nal.usda.gov/ndb

问题

你好,我尝试将来自api.nal.usda.gov/ndb的JSON响应解组成结构体,但它总是返回空值:

  1. { []}

示例JSON:

  1. {
  2. "list": {
  3. "q": "butter",
  4. "sr": "28",
  5. "ds": "any",
  6. "start": 0,
  7. "end": 50,
  8. "total": 4003,
  9. "group": "",
  10. "sort": "r",
  11. "item": [
  12. {
  13. "offset": 0,
  14. "group": "Branded Food Products Database",
  15. "name": "BLUE BUNNY, PEANUT BUTTER PANIC, ICE CREAM, POWERFUL PEANUT BUTTER ICE CREAM CHARGED WITH PEANUT BUTTER AND FUDGE SAUCES AND OVERLOADED WITH PEANUT BUTTER CUPS, UPC: 070640034086",
  16. "ndbno": "45011419",
  17. "ds": "BL"
  18. },
  19. {
  20. "offset": 1,
  21. "group": "Branded Food Products Database",
  22. "name": "BLUE BUNNY, ICE CREAM, PEANUT BUTTER PARTY, PEANUT BUTTER ICE CREAM, PEANUT BUTTER AND FUDGE SWIRLS, PEANUT BUTTER CUPS, UPC: 070640012411",
  23. "ndbno": "45110466",
  24. "ds": "BL"
  25. }
  26. ]
  27. }
  28. }

我使用https://jsonformatter.curiousconcept.com/检查了JSON响应,它是正确的。希望你能告诉我为什么会出现这种情况,因为我对Golang还很陌生。

我的结构体定义如下:

  1. type List struct {
  2. Q string `json:"q,omitempty"`
  3. Sr string `json:"sr,omitempty"`
  4. Ds string `json:"ds,omitempty"`
  5. Start string `json:"start,omitempty"`
  6. End string `json:"end,omitempty"`
  7. Total string `json:"total,omitempty"`
  8. Group string `json:"group,omitempty"`
  9. Sort string `json:"sort,omitempty"`
  10. Item []Item `json:"item,omitempty"`
  11. }
  12. type Item struct {
  13. Offset string `json:"offset,omitempty"`
  14. Group string `json:"group,omitempty"` //food group to which the food belongs
  15. Name string `json:"name,omitempty"` //the food’s name
  16. Ndbno string `json:"ndbno,omitempty"` //the food’s NDB Number
  17. Ds string `json:"ds,omitempty"` //Data source: BL=Branded Food Products or SR=Standard Release
  18. }

代码部分如下:

  1. func (sr *SearchRequest) fetch() {
  2. url := "https://api.nal.usda.gov/ndb/search/?&" +
  3. "format=" + sr.format +
  4. "&q=" + sr.q +
  5. "&sort=" + sr.sort +
  6. "&max=" + strconv.FormatInt(sr.max, 10) +
  7. "&offset=" + strconv.FormatInt(sr.offset, 10) +
  8. "&api_key=" + sr.c.ApiKey
  9. r, err := http.Get(url)
  10. if err != nil {
  11. panic(err.Error())
  12. }
  13. defer r.Body.Close()
  14. b, err := ioutil.ReadAll(r.Body)
  15. if err != nil {
  16. panic(err.Error())
  17. }
  18. l := new(List)
  19. err = json.Unmarshal(b, &l)
  20. if err != nil {
  21. fmt.Println(err)
  22. }
  23. fmt.Println(l)
  24. }
英文:

Hello I try to unmarshal the JSON response from api.nal.usda.gov/ndb into struct, but it always returns empty:

  1. { []}

Example JSON:

  1. {
  2. "list": {
  3. "q": "butter",
  4. "sr": "28",
  5. "ds": "any",
  6. "start": 0,
  7. "end": 50,
  8. "total": 4003,
  9. "group": "",
  10. "sort": "r",
  11. "item": [
  12. {
  13. "offset": 0,
  14. "group": "Branded Food Products Database",
  15. "name": "BLUE BUNNY, PEANUT BUTTER PANIC, ICE CREAM, POWERFUL PEANUT BUTTER ICE CREAM CHARGED WITH PEANUT BUTTER AND FUDGE SAUCES AND OVERLOADED WITH PEANUT BUTTER CUPS, UPC: 070640034086",
  16. "ndbno": "45011419",
  17. "ds": "BL"
  18. },
  19. {
  20. "offset": 1,
  21. "group": "Branded Food Products Database",
  22. "name": "BLUE BUNNY, ICE CREAM, PEANUT BUTTER PARTY, PEANUT BUTTER ICE CREAM, PEANUT BUTTER AND FUDGE SWIRLS, PEANUT BUTTER CUPS, UPC: 070640012411",
  23. "ndbno": "45110466",
  24. "ds": "BL"
  25. }
  26. ]
  27. }
  28. }

I checked the JSON response with https://jsonformatter.curiousconcept.com/, and it´s fine. I hope you can tell me why, since I am quite new to Golang.

My Structs:

  1. type List struct {
  2. Q string `json:"q,omitempty"`
  3. Sr string `json:"sr,omitempty"`
  4. Ds string `json:"ds,omitempty"`
  5. Start string `json:"start,omitempty"`
  6. End string `json:"end,omitempty"`
  7. Total string `json:"total,omitempty"`
  8. Group string `json:"group,omitempty"`
  9. Sort string `json:"sort,omitempty"`
  10. Item []Item `json:"item,omitempty"`
  11. }
  12. type Item struct {
  13. Offset string `json:"offset,omitempty"`
  14. Group string `json:"group,omitempty"` //food group to which the food belongs
  15. Name string `json:"name,omitempty"` //the food’s name
  16. Ndbno string `json:"nbno,omitempty"` //the food’s NDB Number
  17. Ds string `json:"ds,omitempty"` //Data source: BL=Branded Food Products or SR=Standard Release
  18. }

Code:

  1. func (sr *SearchRequest) fetch() {
  2. url := "https://api.nal.usda.gov/ndb/search/?" +
  3. "format=" + sr.format +
  4. "&q=" + sr.q +
  5. "&sort=" + sr.sort +
  6. "&max=" + strconv.FormatInt(sr.max, 10) +
  7. "&offset=" + strconv.FormatInt(sr.offset, 10) +
  8. "&api_key=" + sr.c.ApiKey
  9. r, err := http.Get(url)
  10. if err != nil {
  11. panic(err.Error())
  12. }
  13. defer r.Body.Close()
  14. b, err := ioutil.ReadAll(r.Body)
  15. if err != nil {
  16. panic(err.Error())
  17. }
  18. l := new(List)
  19. err = json.Unmarshal(b, &l)
  20. if err != nil {
  21. fmt.Println(err)
  22. }
  23. fmt.Println(l)
  24. }

答案1

得分: 2

Go类型与JSON的结构不匹配。JSON中还有一个更深层次的对象。尝试使用以下代码:

  1. var v struct {
  2. List List
  3. }
  4. err := json.Unmarshal([]byte(data), &v)

JSON中的一些字符串字段对应于数字。请使用数值类型(int、float64等)声明这些字段。

playground示例

英文:

The Go types do not match the structure of the JSON. There's one more level of objects in the JSON. Try this:

  1. var v struct {
  2. List List
  3. }
  4. err := json.Unmarshal([]byte(data), &v)

Some of the string fields correspond to numbers in the JSON. Declare these fields with a numerical type (int, float64, ...).

playground example

答案2

得分: 0

IMHO你的结构与提供的JSON不匹配。请尝试以下代码:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type MyItem struct {
  7. Q string `json:"q,omitempty"`
  8. Sr string `json:"sr,omitempty"`
  9. Ds string `json:"ds,omitempty"`
  10. Start int `json:"start,omitempty"`
  11. End int `json:"end,omitempty"`
  12. Total int `json:"total,omitempty"`
  13. Group string `json:"group,omitempty"`
  14. Sort string `json:"sort,omitempty"`
  15. Item []Item `json:"item,omitempty"`
  16. }
  17. type MyList struct {
  18. List MyItem `json:"list"`
  19. }
  20. type Item struct {
  21. Offset int `json:"offset,omitempty"`
  22. Group string `json:"group,omitempty"` // 食物所属的食物组
  23. Name string `json:"name,omitempty"` // 食物的名称
  24. Ndbno string `json:"ndbno,omitempty"` // 食物的NDB编号
  25. Ds string `json:"ds,omitempty"` // 数据来源:BL=品牌食品产品或SR=标准发布
  26. }
  27. var jsonStr = `{
  28. "list": {
  29. "q": "butter",
  30. "sr": "28",
  31. "ds": "any",
  32. "start": 0,
  33. "end": 50,
  34. "total": 4003,
  35. "group": "",
  36. "sort": "r",
  37. "item": [
  38. {
  39. "offset": 0,
  40. "group": "Branded Food Products Database",
  41. "name": "BLUE BUNNY, PEANUT BUTTER PANIC, ICE CREAM, POWERFUL PEANUT BUTTER ICE CREAM CHARGED WITH PEANUT BUTTER AND FUDGE SAUCES AND OVERLOADED WITH PEANUT BUTTER CUPS, UPC: 070640034086",
  42. "ndbno": "45011419",
  43. "ds": "BL"
  44. },
  45. {
  46. "offset": 1,
  47. "group": "Branded Food Products Database",
  48. "name": "BLUE BUNNY, ICE CREAM, PEANUT BUTTER PARTY, PEANUT BUTTER ICE CREAM, PEANUT BUTTER AND FUDGE SWIRLS, PEANUT BUTTER CUPS, UPC: 070640012411",
  49. "ndbno": "45110466",
  50. "ds": "BL"
  51. }
  52. ]
  53. }
  54. }`
  55. func main() {
  56. b := jsonStr
  57. l := new(MyList)
  58. err := json.Unmarshal([]byte(b), &l)
  59. if err != nil {
  60. fmt.Println(err)
  61. }
  62. fmt.Println(l)
  63. }

编辑:使用spew.Dump(l)打印结果可能不易阅读,因此这里提供使用spew.Dump(l)的结果(go get -u github.com/davecgh/go-spew/spew):

  1. List: (main.MyItem) {
  2. Q: (string) (len=6) "butter",
  3. Sr: (string) (len=2) "28",
  4. Ds: (string) (len=3) "any",
  5. Start: (int) 0,
  6. End: (int) 50,
  7. Total: (int) 4003,
  8. Group: (string) "",
  9. Sort: (string) (len=1) "r",
  10. Item: ([]main.Item) (len=2 cap=4) {
  11. (main.Item) {
  12. Offset: (int) 0,
  13. Group: (string) (len=30) "Branded Food Products Database",
  14. Name: (string) (len=178) "BLUE BUNNY, PEANUT BUTTER PANIC, ICE CREAM, POWERFUL PEANUT BUTTER ICE CREAM CHARGED WITH PEANUT BUTTER AND FUDGE SAUCES AND OVERLOADED WITH PEANUT BUTTER CUPS, UPC: 070640034086",
  15. Ndbno: (string) "",
  16. Ds: (string) (len=2) "BL"
  17. },
  18. (main.Item) {
  19. Offset: (int) 1,
  20. Group: (string) (len=30) "Branded Food Products Database",
  21. Name: (string) (len=138) "BLUE BUNNY, ICE CREAM, PEANUT BUTTER PARTY, PEANUT BUTTER ICE CREAM, PEANUT BUTTER AND FUDGE SWIRLS, PEANUT BUTTER CUPS, UPC: 070640012411",
  22. Ndbno: (string) "",
  23. Ds: (string) (len=2) "BL"
  24. }
  25. }
  26. }
英文:

IMHO your struct doesn't match to JSON you provided. Try:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type MyItem struct {
  7. Q string `json:"q,omitempty"`
  8. Sr string `json:"sr,omitempty"`
  9. Ds string `json:"ds,omitempty"`
  10. Start int `json:"start,omitempty"`
  11. End int `json:"end,omitempty"`
  12. Total int `json:"total,omitempty"`
  13. Group string `json:"group,omitempty"`
  14. Sort string `json:"sort,omitempty"`
  15. Item []Item `json:"item,omitempty"`
  16. }
  17. type MyList struct {
  18. List MyItem `json:"list"`
  19. }
  20. type Item struct {
  21. Offset int `json:"offset,omitempty"`
  22. Group string `json:"group,omitempty"` //food group to which the food belongs
  23. Name string `json:"name,omitempty"` //the food’s name
  24. Ndbno string `json:"nbno,omitempty"` //the food’s NDB Number
  25. Ds string `json:"ds,omitempty"` //Data source: BL=Branded Food Products or SR=Standard Release
  26. }
  27. var jsonStr = `{
  28. "list": {
  29. "q": "butter",
  30. "sr": "28",
  31. "ds": "any",
  32. "start": 0,
  33. "end": 50,
  34. "total": 4003,
  35. "group": "",
  36. "sort": "r",
  37. "item": [
  38. {
  39. "offset": 0,
  40. "group": "Branded Food Products Database",
  41. "name": "BLUE BUNNY, PEANUT BUTTER PANIC, ICE CREAM, POWERFUL PEANUT BUTTER ICE CREAM CHARGED WITH PEANUT BUTTER AND FUDGE SAUCES AND OVERLOADED WITH PEANUT BUTTER CUPS, UPC: 070640034086",
  42. "ndbno": "45011419",
  43. "ds": "BL"
  44. },
  45. {
  46. "offset": 1,
  47. "group": "Branded Food Products Database",
  48. "name": "BLUE BUNNY, ICE CREAM, PEANUT BUTTER PARTY, PEANUT BUTTER ICE CREAM, PEANUT BUTTER AND FUDGE SWIRLS, PEANUT BUTTER CUPS, UPC: 070640012411",
  49. "ndbno": "45110466",
  50. "ds": "BL"
  51. }]
  52. }
  53. }`
  54. func main() {
  55. b := jsonStr
  56. l := new(MyList)
  57. err := json.Unmarshal([]byte(b), &l)
  58. if err != nil {
  59. fmt.Println(err)
  60. }
  61. fmt.Println(l)
  62. }

EDIT: It is hard to read result of println or printf with %+v so here is the result with spew.Dump(l) (go get -u github.com/davecgh/go-spew/spew):

  1. List: (main.MyItem) {
  2. Q: (string) (len=6) "butter",
  3. Sr: (string) (len=2) "28",
  4. Ds: (string) (len=3) "any",
  5. Start: (int) 0,
  6. End: (int) 50,
  7. Total: (int) 4003,
  8. Group: (string) "",
  9. Sort: (string) (len=1) "r",
  10. Item: ([]main.Item) (len=2 cap=4) {
  11. (main.Item) {
  12. Offset: (int) 0,
  13. Group: (string) (len=30) "Branded Food Products Database",
  14. Name: (string) (len=178) "BLUE BUNNY, PEANUT BUTTER PANIC, ICE CREAM, POWERFUL PEANUT BUTTER ICE CREAM CHARGED WITH PEANUT BUTTER AND FUDGE SAUCES AND OVERLOADED WITH PEANUT BUTTER CUPS, UPC: 070640034086",
  15. Ndbno: (string) "",
  16. Ds: (string) (len=2) "BL"
  17. },
  18. (main.Item) {
  19. Offset: (int) 1,
  20. Group: (string) (len=30) "Branded Food Products Database",
  21. Name: (string) (len=138) "BLUE BUNNY, ICE CREAM, PEANUT BUTTER PARTY, PEANUT BUTTER ICE CREAM, PEANUT BUTTER AND FUDGE SWIRLS, PEANUT BUTTER CUPS, UPC: 070640012411",
  22. Ndbno: (string) "",
  23. Ds: (string) (len=2) "BL"
  24. }
  25. }
  26. }
  27. })

huangapple
  • 本文由 发表于 2017年4月11日 23:02:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/43349648.html
匿名

发表评论

匿名网友

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

确定