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

时间:2012-11-27 21:36:39

标签: json go

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

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

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

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

我想用json:... struct标签指定JSON字段名称,但是我不知道要使用什么作为标记,因为它不是我感兴趣的顶级对象。我对此没有发现任何信息在encoding/json包文档中,也在热门博客文章JSON and Go中。我还测试了motherparents/motherparents.mother

5 个答案:

答案 0 :(得分:19)

只要传入的数据不是太动态,就可以使用结构。

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

答案 1 :(得分:18)

不幸的是,与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字段重构为方法调用不在菜单上,那么您可能需要创建一个单独的方法来解码并符合您当前的结构

答案 2 :(得分: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))
}

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

答案 3 :(得分:5)

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

reg_items

答案 4 :(得分: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)  
}