41

我有一个类似于这个的 JSON 对象:

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

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

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

我想用json:...struct 标签指定 JSON 字段名称,但是我不知道用什么作为标签,因为它不是我感兴趣的顶级对象。我在encoding/json包文档和流行的博客文章JSON 和 Go。我也测试过motherparents/motherparents.mother

4

5 回答 5

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"
        }
    }`

    // 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)
}
于 2012-11-27T22:04:02.737 回答
19

不幸的是,与 不同的是encoding/xml,该json包不提供访问嵌套值的方法。您需要创建一个单独的父母结构或将类型分配为map[string]string. 例如:

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

然后,您可以像这样为母亲提供吸气剂:

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

这可能会或可能不会影响您当前的代码库,并且如果将Mother字段重构为方法调用不在菜单上,那么您可能需要创建一个单独的方法来解码并符合您当前的结构。

于 2012-11-27T22:41:24.147 回答
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"
        }
    }`

    // 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))
}

可能有更好的方法。我期待看到其他答案。:-)

于 2012-11-27T21:50:21.553 回答
5

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

name := gjson.Get(json, "name")
mother := gjson.Get(json, "parents.mother")
于 2016-11-27T11:41:53.873 回答
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)  
}
于 2013-06-27T09:03:41.480 回答