如何解析嵌套的JSON对象中的内部字段

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

How to parse an inner field in a nested JSON object

问题

{
"name": "Cain",
"parents": {
"mother" : "Eve",
"father" : "Adam"
}
}

现在我想将"name"和"mother"解析到这个结构体中:

struct {
Name String
Mother String json:"???"
}

我想用json:...结构标签指定JSON字段名,但是我不知道该使用什么作为标签,因为我对顶层对象不感兴趣。我在encoding/json包的文档中找不到关于此的任何信息,也没有在流行的博客文章JSON and Go中找到。我还测试了motherparents/motherparents.mother

英文:

I have a JSON object similar to this one:

{
  "name": "Cain",
  "parents": {
    "mother" : "Eve",
    "father" : "Adam"
  }
}

Now I want to parse "name" and "mother" into this struct:

struct {
  Name String
  Mother String `json:"???"`
}

I want to specify the JSON field name with the json:... struct tag, however I don't know what to use as tag, because it is not the top object I am interested in. I found nothing about this in the encoding/json package docs nor in the popular blog post JSON and Go. I also tested mother, parents/mother and parents.mother.

答案1

得分: 20

你可以使用结构体,只要你的输入数据不太动态。

http://play.golang.org/p/bUZ8l6WgvL

package main

import (
	"fmt"
	"encoding/json"
	)

type User struct {
	Name string
	Parents struct {
		Mother string
		Father string
	}
}

func main() {
	encoded := `{
	    "name": "Cain",
	    "parents": {
	        "mother": "Eve",
	        "father": "Adam"
	    }
	}`

	// 解码json对象
	u := &User{}
	err := json.Unmarshal([]byte(encoded), &u)
	if err != nil {
		panic(err)
	}

	// 打印出母亲和父亲
	fmt.Printf("Mother: %s\n", u.Parents.Mother)
	fmt.Printf("Father: %s\n", u.Parents.Father)
}
英文:

You could use structs so long as your incoming data isn't too dynamic.

http://play.golang.org/p/bUZ8l6WgvL

package main

import (
	"fmt"
	"encoding/json"
	)

type User struct {
	Name string
	Parents struct {
		Mother string
		Father string
	}
}

func main() {
	encoded := `{
	    "name": "Cain",
	    "parents": {
	        "mother": "Eve",
	        "father": "Adam"
	    }
	}`

	// Decode the json object
	u := &User{}
	err := json.Unmarshal([]byte(encoded), &u)
	if err != nil {
		panic(err)
	}

	// Print out mother and father
	fmt.Printf("Mother: %s\n", u.Parents.Mother)
	fmt.Printf("Father: %s\n", u.Parents.Father)
}

答案2

得分: 19

不幸的是,与encoding/xml不同,json包没有提供访问嵌套值的方法。您可以创建一个单独的Parents结构体或将类型分配为map[string]string。例如:

type Person struct {
    Name string
    Parents map[string]string
}

然后,您可以提供一个获取母亲的方法:

func (p *Person) Mother() string {
    return p.Parents["mother"]
}

这可能与您当前的代码库有关,如果将Mother字段重构为方法调用不在计划中,那么您可能需要创建一个单独的方法来进行解码并符合您当前的结构体。

英文:

Unfortunately, unlike encoding/xml, the json package doesn't provide a way to access nested values. You'll want to either create a separate Parents struct or assign the type to be map[string]string. For example:

type Person struct {
    Name string
    Parents map[string]string
}

You could then provide a getter for mother as so:

func (p *Person) Mother() string {
    return p.Parents["mother"]
}

This may or may not play into your current codebase and if refactoring the Mother field to a method call is not on the menu, then you may want to create a separate method for decoding and conforming to your current struct.

答案3

得分: 6

这是我在Go Playground中快速编写的一些代码

http://play.golang.org/p/PiWwpUbBqt

package main

import (
	"fmt"
	"encoding/json"
	)

func main() {
	encoded := `{
	    "name": "Cain",
	    "parents": {
	        "mother": "Eve",
            "father": "Adam"
	    }
	}`

	// 解码json对象
	var j map[string]interface{}
	err := json.Unmarshal([]byte(encoded), &j)
	if err != nil {
		panic(err)
	}

	// 提取出parents对象
	parents := j["parents"].(map[string]interface{})

	// 打印出母亲和父亲
	fmt.Printf("Mother: %s\n", parents["mother"].(string))
	fmt.Printf("Father: %s\n", parents["father"].(string))
}

可能有更好的方法。我期待看到其他答案。 如何解析嵌套的JSON对象中的内部字段

英文:

Here's some code I baked up real quick in the Go Playground

http://play.golang.org/p/PiWwpUbBqt

package main

import (
	"fmt"
	"encoding/json"
	)

func main() {
	encoded := `{
	    "name": "Cain",
	    "parents": {
	        "mother": "Eve"
            "father": "Adam"
	    }
	}`

	// Decode the json object
	var j map[string]interface{}
	err := json.Unmarshal([]byte(encoded), &j)
	if err != nil {
		panic(err)
	}

	// pull out the parents object
	parents := j["parents"].(map[string]interface{})

	// Print out mother and father
	fmt.Printf("Mother: %s\n", parents["mother"].(string))
	fmt.Printf("Father: %s\n", parents["father"].(string))
}

There might be a better way. I'm looking forward to seeing the other answers. 如何解析嵌套的JSON对象中的内部字段

答案4

得分: 5

最近,gjson 支持选择嵌套的 JSON 属性。

name := gjson.Get(json, "name")
mother := gjson.Get(json, "parents.mother")
英文:

More recently, gjson supports selection of nested JSON properties.

name := gjson.Get(json, "name")
mother := gjson.Get(json, "parents.mother")

答案5

得分: 2

如何使用上面建议的中间结构体进行解析,然后将相关的值放入您的“真实”结构体中?

import (
    "fmt"
    "encoding/json"
)

type MyObject struct{
  Name string
  Mother string
}

type MyParseObj struct{
   Name string
   Parents struct {
         Mother string
         Father string
   } 
}


func main() {
    encoded := `{
         "name": "Cain",
         "parents": {
             "mother": "Eve",
             "father": "Adam"
         }
    }`

    pj := &MyParseObj{}
    if err := json.Unmarshal([]byte(encoded), pj); err != nil {
        return
    }
    final := &MyObject{Name: pj.Name, Mother: pj.Parents.Mother}
    fmt.Println(final)  
}
英文:

How about using an intermediary struct as the one suggested above for parsing, and then putting the relevant values in your "real" struct?

import (
    "fmt"
    "encoding/json"
    )

type MyObject struct{
  Name string
  Mother string
}

type MyParseObj struct{
   Name string
   Parents struct {
         Mother string
         Father string
   } 
}


func main() {
    encoded := `{
         "name": "Cain",
         "parents": {
             "mother": "Eve",
             "father": "Adam"
         }
    }`

    pj := &MyParseObj{}
    if err := json.Unmarshal([]byte(encoded), pj); err != nil {
        return
    }
    final := &MyObject{Name: pj.Name, Mother: pj.Parents.Mother}
    fmt.Println(final)  
}

huangapple
  • 本文由 发表于 2012年11月28日 05:36:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/13593519.html
匿名

发表评论

匿名网友

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

确定