How to parse an inner field in a nested JSON object

后端 未结 5 1233
一生所求
一生所求 2021-01-31 08:26

I have a JSON object similar to this one:

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

No

相关标签:
5条回答
  • 2021-01-31 08:37

    More recently, gjson supports selection of nested JSON properties.

    name := gjson.Get(json, "name")
    mother := gjson.Get(json, "parents.mother")
    
    0 讨论(0)
  • 2021-01-31 08:45

    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. :-)

    0 讨论(0)
  • 2021-01-31 08:56

    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)
    }
    
    0 讨论(0)
  • 2021-01-31 08:56

    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)  
    }
    
    0 讨论(0)
  • 2021-01-31 09:02

    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.

    0 讨论(0)
提交回复
热议问题