I have a JSON object similar to this one:
我有一个类似于这个的JSON对象:
{
"name": "Cain",
"parents": {
"mother" : "Eve",
"father" : "Adam"
}
}
Now I want to parse "name" and "mother" into this struct:
现在我想把name和mother解析到这个结构中:
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
.
我想用JSON指定JSON字段名:…struct tag,我不知道用什么作为tag,因为它不是我感兴趣的最上面的对象。我在编码/json包文档或流行的博客post json和Go中都找不到这一点。我还测试了母亲、父母/母亲和父母。
5 个解决方案
#1
16
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:
不幸的是,与编码/xml不同,json包没有提供访问嵌套值的方法。您将希望创建一个单独的父结构体,或者将类型赋值为map[string]string。例如:
type Person struct {
Name string
Parents map[string]string
}
You could then provide a getter for mother as so:
然后,您可以为母亲提供一个getter:
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.
这可能会影响到当前的代码基,也可能不会,如果将母字段重构为方法调用不在菜单上,那么您可能希望创建一个单独的方法来解码并与当前结构保持一致。
#2
18
You could use structs so long as your incoming data isn't too dynamic.
只要传入的数据不太动态,就可以使用struct。
http://play.golang.org/p/bUZ8l6WgvL
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)
}
#3
6
Here's some code I baked up real quick in the Go Playground
这里有一些我在操场上快速烘焙的代码。
http://play.golang.org/p/PiWwpUbBqt
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. :-)
也许有更好的办法。我期待看到其他的答案。:-)
#4
3
More recently, gjson supports selection of nested JSON properties.
最近,gjson支持选择嵌套的JSON属性。
name := gjson.Get(json, "name")
mother := gjson.Get(json, "parents.mother")
#5
2
How about using an intermediary struct as the one suggested above for parsing, and then putting the relevant values in your "real" struct?
像上面建议的那样使用中间结构来进行解析,然后将相关值放入“real”结构中,怎么样?
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)
}
#1
16
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:
不幸的是,与编码/xml不同,json包没有提供访问嵌套值的方法。您将希望创建一个单独的父结构体,或者将类型赋值为map[string]string。例如:
type Person struct {
Name string
Parents map[string]string
}
You could then provide a getter for mother as so:
然后,您可以为母亲提供一个getter:
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.
这可能会影响到当前的代码基,也可能不会,如果将母字段重构为方法调用不在菜单上,那么您可能希望创建一个单独的方法来解码并与当前结构保持一致。
#2
18
You could use structs so long as your incoming data isn't too dynamic.
只要传入的数据不太动态,就可以使用struct。
http://play.golang.org/p/bUZ8l6WgvL
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)
}
#3
6
Here's some code I baked up real quick in the Go Playground
这里有一些我在操场上快速烘焙的代码。
http://play.golang.org/p/PiWwpUbBqt
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. :-)
也许有更好的办法。我期待看到其他的答案。:-)
#4
3
More recently, gjson supports selection of nested JSON properties.
最近,gjson支持选择嵌套的JSON属性。
name := gjson.Get(json, "name")
mother := gjson.Get(json, "parents.mother")
#5
2
How about using an intermediary struct as the one suggested above for parsing, and then putting the relevant values in your "real" struct?
像上面建议的那样使用中间结构来进行解析,然后将相关值放入“real”结构中,怎么样?
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)
}