英文:
Golang unmarshall JSON from api.nal.usda.gov/ndb
问题
你好,我尝试将来自api.nal.usda.gov/ndb的JSON响应解组成结构体,但它总是返回空值:
{ []}
示例JSON:
{
"list": {
"q": "butter",
"sr": "28",
"ds": "any",
"start": 0,
"end": 50,
"total": 4003,
"group": "",
"sort": "r",
"item": [
{
"offset": 0,
"group": "Branded Food Products Database",
"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",
"ndbno": "45011419",
"ds": "BL"
},
{
"offset": 1,
"group": "Branded Food Products Database",
"name": "BLUE BUNNY, ICE CREAM, PEANUT BUTTER PARTY, PEANUT BUTTER ICE CREAM, PEANUT BUTTER AND FUDGE SWIRLS, PEANUT BUTTER CUPS, UPC: 070640012411",
"ndbno": "45110466",
"ds": "BL"
}
]
}
}
我使用https://jsonformatter.curiousconcept.com/检查了JSON响应,它是正确的。希望你能告诉我为什么会出现这种情况,因为我对Golang还很陌生。
我的结构体定义如下:
type List struct {
Q string `json:"q,omitempty"`
Sr string `json:"sr,omitempty"`
Ds string `json:"ds,omitempty"`
Start string `json:"start,omitempty"`
End string `json:"end,omitempty"`
Total string `json:"total,omitempty"`
Group string `json:"group,omitempty"`
Sort string `json:"sort,omitempty"`
Item []Item `json:"item,omitempty"`
}
type Item struct {
Offset string `json:"offset,omitempty"`
Group string `json:"group,omitempty"` //food group to which the food belongs
Name string `json:"name,omitempty"` //the food’s name
Ndbno string `json:"ndbno,omitempty"` //the food’s NDB Number
Ds string `json:"ds,omitempty"` //Data source: BL=Branded Food Products or SR=Standard Release
}
代码部分如下:
func (sr *SearchRequest) fetch() {
url := "https://api.nal.usda.gov/ndb/search/?&" +
"format=" + sr.format +
"&q=" + sr.q +
"&sort=" + sr.sort +
"&max=" + strconv.FormatInt(sr.max, 10) +
"&offset=" + strconv.FormatInt(sr.offset, 10) +
"&api_key=" + sr.c.ApiKey
r, err := http.Get(url)
if err != nil {
panic(err.Error())
}
defer r.Body.Close()
b, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err.Error())
}
l := new(List)
err = json.Unmarshal(b, &l)
if err != nil {
fmt.Println(err)
}
fmt.Println(l)
}
英文:
Hello I try to unmarshal the JSON response from api.nal.usda.gov/ndb into struct, but it always returns empty:
{ []}
Example JSON:
{
"list": {
"q": "butter",
"sr": "28",
"ds": "any",
"start": 0,
"end": 50,
"total": 4003,
"group": "",
"sort": "r",
"item": [
{
"offset": 0,
"group": "Branded Food Products Database",
"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",
"ndbno": "45011419",
"ds": "BL"
},
{
"offset": 1,
"group": "Branded Food Products Database",
"name": "BLUE BUNNY, ICE CREAM, PEANUT BUTTER PARTY, PEANUT BUTTER ICE CREAM, PEANUT BUTTER AND FUDGE SWIRLS, PEANUT BUTTER CUPS, UPC: 070640012411",
"ndbno": "45110466",
"ds": "BL"
}
]
}
}
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:
type List struct {
Q string `json:"q,omitempty"`
Sr string `json:"sr,omitempty"`
Ds string `json:"ds,omitempty"`
Start string `json:"start,omitempty"`
End string `json:"end,omitempty"`
Total string `json:"total,omitempty"`
Group string `json:"group,omitempty"`
Sort string `json:"sort,omitempty"`
Item []Item `json:"item,omitempty"`
}
type Item struct {
Offset string `json:"offset,omitempty"`
Group string `json:"group,omitempty"` //food group to which the food belongs
Name string `json:"name,omitempty"` //the food’s name
Ndbno string `json:"nbno,omitempty"` //the food’s NDB Number
Ds string `json:"ds,omitempty"` //Data source: BL=Branded Food Products or SR=Standard Release
}
Code:
func (sr *SearchRequest) fetch() {
url := "https://api.nal.usda.gov/ndb/search/?" +
"format=" + sr.format +
"&q=" + sr.q +
"&sort=" + sr.sort +
"&max=" + strconv.FormatInt(sr.max, 10) +
"&offset=" + strconv.FormatInt(sr.offset, 10) +
"&api_key=" + sr.c.ApiKey
r, err := http.Get(url)
if err != nil {
panic(err.Error())
}
defer r.Body.Close()
b, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err.Error())
}
l := new(List)
err = json.Unmarshal(b, &l)
if err != nil {
fmt.Println(err)
}
fmt.Println(l)
}
答案1
得分: 2
Go类型与JSON的结构不匹配。JSON中还有一个更深层次的对象。尝试使用以下代码:
var v struct {
List List
}
err := json.Unmarshal([]byte(data), &v)
JSON中的一些字符串字段对应于数字。请使用数值类型(int、float64等)声明这些字段。
英文:
The Go types do not match the structure of the JSON. There's one more level of objects in the JSON. Try this:
var v struct {
List List
}
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, ...).
答案2
得分: 0
IMHO你的结构与提供的JSON不匹配。请尝试以下代码:
package main
import (
"encoding/json"
"fmt"
)
type MyItem struct {
Q string `json:"q,omitempty"`
Sr string `json:"sr,omitempty"`
Ds string `json:"ds,omitempty"`
Start int `json:"start,omitempty"`
End int `json:"end,omitempty"`
Total int `json:"total,omitempty"`
Group string `json:"group,omitempty"`
Sort string `json:"sort,omitempty"`
Item []Item `json:"item,omitempty"`
}
type MyList struct {
List MyItem `json:"list"`
}
type Item struct {
Offset int `json:"offset,omitempty"`
Group string `json:"group,omitempty"` // 食物所属的食物组
Name string `json:"name,omitempty"` // 食物的名称
Ndbno string `json:"ndbno,omitempty"` // 食物的NDB编号
Ds string `json:"ds,omitempty"` // 数据来源:BL=品牌食品产品或SR=标准发布
}
var jsonStr = `{
"list": {
"q": "butter",
"sr": "28",
"ds": "any",
"start": 0,
"end": 50,
"total": 4003,
"group": "",
"sort": "r",
"item": [
{
"offset": 0,
"group": "Branded Food Products Database",
"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",
"ndbno": "45011419",
"ds": "BL"
},
{
"offset": 1,
"group": "Branded Food Products Database",
"name": "BLUE BUNNY, ICE CREAM, PEANUT BUTTER PARTY, PEANUT BUTTER ICE CREAM, PEANUT BUTTER AND FUDGE SWIRLS, PEANUT BUTTER CUPS, UPC: 070640012411",
"ndbno": "45110466",
"ds": "BL"
}
]
}
}`
func main() {
b := jsonStr
l := new(MyList)
err := json.Unmarshal([]byte(b), &l)
if err != nil {
fmt.Println(err)
}
fmt.Println(l)
}
编辑:使用spew.Dump(l)打印结果可能不易阅读,因此这里提供使用spew.Dump(l)的结果(go get -u github.com/davecgh/go-spew/spew):
List: (main.MyItem) {
Q: (string) (len=6) "butter",
Sr: (string) (len=2) "28",
Ds: (string) (len=3) "any",
Start: (int) 0,
End: (int) 50,
Total: (int) 4003,
Group: (string) "",
Sort: (string) (len=1) "r",
Item: ([]main.Item) (len=2 cap=4) {
(main.Item) {
Offset: (int) 0,
Group: (string) (len=30) "Branded Food Products Database",
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",
Ndbno: (string) "",
Ds: (string) (len=2) "BL"
},
(main.Item) {
Offset: (int) 1,
Group: (string) (len=30) "Branded Food Products Database",
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",
Ndbno: (string) "",
Ds: (string) (len=2) "BL"
}
}
}
英文:
IMHO your struct doesn't match to JSON you provided. Try:
package main
import (
"encoding/json"
"fmt"
)
type MyItem struct {
Q string `json:"q,omitempty"`
Sr string `json:"sr,omitempty"`
Ds string `json:"ds,omitempty"`
Start int `json:"start,omitempty"`
End int `json:"end,omitempty"`
Total int `json:"total,omitempty"`
Group string `json:"group,omitempty"`
Sort string `json:"sort,omitempty"`
Item []Item `json:"item,omitempty"`
}
type MyList struct {
List MyItem `json:"list"`
}
type Item struct {
Offset int `json:"offset,omitempty"`
Group string `json:"group,omitempty"` //food group to which the food belongs
Name string `json:"name,omitempty"` //the food’s name
Ndbno string `json:"nbno,omitempty"` //the food’s NDB Number
Ds string `json:"ds,omitempty"` //Data source: BL=Branded Food Products or SR=Standard Release
}
var jsonStr = `{
"list": {
"q": "butter",
"sr": "28",
"ds": "any",
"start": 0,
"end": 50,
"total": 4003,
"group": "",
"sort": "r",
"item": [
{
"offset": 0,
"group": "Branded Food Products Database",
"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",
"ndbno": "45011419",
"ds": "BL"
},
{
"offset": 1,
"group": "Branded Food Products Database",
"name": "BLUE BUNNY, ICE CREAM, PEANUT BUTTER PARTY, PEANUT BUTTER ICE CREAM, PEANUT BUTTER AND FUDGE SWIRLS, PEANUT BUTTER CUPS, UPC: 070640012411",
"ndbno": "45110466",
"ds": "BL"
}]
}
}`
func main() {
b := jsonStr
l := new(MyList)
err := json.Unmarshal([]byte(b), &l)
if err != nil {
fmt.Println(err)
}
fmt.Println(l)
}
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):
List: (main.MyItem) {
Q: (string) (len=6) "butter",
Sr: (string) (len=2) "28",
Ds: (string) (len=3) "any",
Start: (int) 0,
End: (int) 50,
Total: (int) 4003,
Group: (string) "",
Sort: (string) (len=1) "r",
Item: ([]main.Item) (len=2 cap=4) {
(main.Item) {
Offset: (int) 0,
Group: (string) (len=30) "Branded Food Products Database",
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",
Ndbno: (string) "",
Ds: (string) (len=2) "BL"
},
(main.Item) {
Offset: (int) 1,
Group: (string) (len=30) "Branded Food Products Database",
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",
Ndbno: (string) "",
Ds: (string) (len=2) "BL"
}
}
}
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论