dragonmeng2002
2012-11-27 21:36
浏览 610

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

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.

图片转代码服务由CSDN问答提供 功能建议

我有一个与此对象相似的JSON对象:

   {
“ name”:“ Cain”,
“ parents”:{
“ mother”:“ Eve”,
“ father”:“ Adam” 
} 
} 
  <  / pre> 
 
 

现在我想将“ name”和“ mother”解析为该结构:

  struct {
 Name String 
 Mother String  json:“ ???”`
} 
   
 
 

我想用 json:... struct标记,但是我不知道该用什么,因为它不是我感兴趣的顶级对象。在 encoding / json 包文档或热门博客文章 JSON和Go 。 我还测试了 mother parents / mother parents.mother

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • douna2917 2012-11-27 22:41
    已采纳

    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.

    点赞 打赏 评论
  • douliu3831 2012-11-27 21:50

    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
    ", parents["mother"].(string))
        fmt.Printf("Father: %s
    ", parents["father"].(string))
    }
    

    There might be a better way. I'm looking forward to seeing the other answers. :-)

    点赞 打赏 评论
  • donglian4879 2012-11-27 22:04

    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
    ", u.Parents.Mother)
        fmt.Printf("Father: %s
    ", u.Parents.Father)
    }
    
    点赞 打赏 评论
  • dsaj20411 2013-06-27 09:03

    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)  
    }
    
    点赞 打赏 评论
  • douhan6738 2016-11-27 11:41

    More recently, gjson supports selection of nested JSON properties.

    name := gjson.Get(json, "name")
    mother := gjson.Get(json, "parents.mother")
    
    点赞 打赏 评论

相关推荐 更多相似问题