Подтвердить что ты не робот

Как разобрать внутреннее поле в вложенном объекте JSON в Голанге?

У меня есть объект JSON, похожий на этот:

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

Теперь я хочу проанализировать "имя" и "мать" в этой структуре:

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

Я хочу указать имя поля JSON с тегом json:... struct, но я не знаю, что использовать в качестве тега, потому что это не главный объект, который меня интересует. Я ничего не нашел об этом в encoding/json, а также в популярном сообщении в блоге JSON и Go. Я также тестировал mother, parents/mother и parents.mother.

4b9b3361

Ответ 1

К сожалению, в отличие от encoding/xml, пакет json не предоставляет способ доступа к вложенным значениям. Вы захотите либо создать отдельную структуру Parents, либо назначить тип map[string]string. Например:

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

Затем вы могли бы предоставить getter для матери:

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

Это может или не может воспроизводиться в вашей текущей кодовой базе, и если рефакторинг поля Mother в вызове метода отсутствует в меню, тогда вам может понадобиться создать отдельный метод для декодирования и соответствия вашей текущей структуре.

Ответ 2

Вы можете использовать структуры, если ваши входящие данные не слишком динамичны.

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

Здесь некоторый код, который я быстро испек на игровой площадке Go

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

Может быть, лучший способ. Я с нетерпением жду других ответов.: -)

Ответ 4

Совсем недавно gjson поддерживает выбор вложенных свойств JSON.

name := gjson.Get(json, "name")
mother := gjson.Get(json, "parents.mother")

Ответ 5

Как насчет использования промежуточной структуры как предложенной выше для синтаксического анализа, а затем размещения соответствующих значений в вашей "реальной" структуре?

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