How can I parse JSON in GoLang if nested content uses dynamic keys?

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

How can I parse JSON in GoLang if nested content uses dynamic keys?

问题

我从客户端API收到了下面的JSON,但我在获取嵌套的JSON内容方面遇到了困难。如果内部键是动态的,我该如何解析它?

const jsonStream = `
{
    "items": {
        "bvu62fu6dq": {
            "name": "john",
            "age": 23,
            "xyz": "weu33s"
        },
        "iaxdw23fq": {
            "name": "kelly",
            "age": 21,
            "xyz": "weu33s"
        }
    }
}`

我尝试了以下方法,通过循环映射来从上述JSON字符串中提取name和age的值;但它返回了一个带有nil值的映射作为结果。

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}
type Item struct {
    Contact struct {
        Info map[string]Person
    } `json:"items"`
}

func main() {
    dec := json.NewDecoder(strings.NewReader(jsonStream))
    for {
        var item Item
        if err := dec.Decode(&item); err == io.EOF {
            break
        } else if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%s\n", item.Contact.Info["bvu62fu6dq"].Name)
    }
}

你可以在goplayground上查看我尝试的代码。

英文:

I received JSON below from a client API but i am struggling to get nested JSON content. How can I parse it if the inner keys are dynamic?

const jsonStream = `
{
    "items": {
        "bvu62fu6dq": {
            "name": "john",
            "age": 23,
            "xyz": "weu33s"
        },
        "iaxdw23fq": {
            "name": "kelly",
            "age": 21,
            "xyz": "weu33s"
        }
    }
}`

This is what i have tried below by looping the map to extract the value of name and age from above JSON string; but it returns map with nil value as a result.
goplaygound

type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}
type Item struct {
	Contact struct {
		Info map[string]Person
	} `json:"items"`
}

func main() {
	dec := json.NewDecoder(strings.NewReader(jsonStream))
	for {
		var item Item
		if err := dec.Decode(&item); err == io.EOF {
			break
		} else if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%s\n", item.Contact.Info["bvu62fu6dq"].Name)
	}
}

答案1

得分: 6

尝试使用这个替代方案,看起来你只是错误地设置了你的结构:

http://play.golang.org/p/VRKbv-GVQB

你需要解析整个 JSON 字符串,它是一个包含一个名为 items 的单个元素的对象。items 然后包含一个 stringPerson 对象的映射。

如果你只想从每个人中提取 nameage,你可以通过获取 data.Items["bvu62fu6dq"].Name 来实现。

如果你想在 Person 中使用动态键,你需要使用 map[string]interface{} 而不是 Person,以便再次捕获动态键。它可能会像这样:

type Data struct {
    Items map[string]map[string]interface{} `json:"items"`
}
...
fmt.Printf("%v\n", data.Items["bvu62fu6dq"]["name"])
fmt.Printf("%v\n", data.Items["bvu62fu6dq"]["age"])
fmt.Printf("%v\n", data.Items["bvu62fu6dq"]["xyz"])
英文:

Try this instead, looks like you just have your structure set up incorrectly:

http://play.golang.org/p/VRKbv-GVQB

You need to parse the entire json string, which is an object that contains a single element named items. items then contains a map of string -> Person objects.

If you only want to extract name and age from each person, you do it by grabbing data.Items["bvu62fu6dq"].Name.

If you want dynamic keys inside the Person, you'll need to do map[string]interface{} instead of Person in order to capture the dynamic keys again. It would look something like:

type Data struct {
    Items map[string]map[string]interface{} `json:"items"`
}
...
fmt.Printf("%v\n", data.Items["bvu62fu6dq"]["name"]
fmt.Printf("%v\n", data.Items["bvu62fu6dq"]["age"]
fmt.Printf("%v\n", data.Items["bvu62fu6dq"]["xyz"]

huangapple
  • 本文由 发表于 2015年9月27日 15:09:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/32805461.html
匿名

发表评论

匿名网友

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

确定