У меня есть некоторый JSON, и мне нужно получить доступ к его свойствам. Поскольку свойства JSON могут меняться, я не могу создать структуру для размонтирования.

Пример

Содержание JSON может быть следующим:

{"name" : "John Doe", "email" : "john@doe.com"}

или вот это:

{"town" : "Somewhere", "email" : "john@doe.com"}

или что-нибудь еще.

Как я могу получить доступ к каждому из свойств?

tommyd456

Ответов: 3

Ответы (3)

Вы можете размаршалировать его в interface{}. Если вы сделаете это, json.Unmarshal размонтирует объект JSON в карту Go.

Например:

var untypedResult interface{}
err := json.Unmarshal(..., &untypedResult)

result := untypedResult.(map[string]interface{})

// ... now you can iterate over the keys and values of result ...

Посмотрите <http://blog.golang.org/json-and-go#TOC_5.> для полного примера.

Если у вас случайно есть поля, которые могут быть не указаны, вы можете размаршалировать ваш вход в struct с указателем. Если поле отсутствует, указатель будет nil.

package main

import (
    "encoding/json"
    "fmt"
)

type Foo struct {
    A *string
    B *string
    C *int
}

func main() {
    var input string = `{"A": "a","C": 3}`
    var foo Foo
    json.Unmarshal([]byte(input), &foo)
    fmt.Printf("%#v\n", foo)
}

Площадка

Если вам действительно нужно что-то более гибкое, вы также можете размаршрутизировать ваш ввод в map[string]interface{}.

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    var input string = `{"A": "a","C": 3}`
    var foo map[string]interface{} = make(map[string]interface{})
    json.Unmarshal([]byte(input), &foo)
    fmt.Printf("%#v\n", foo)
}

Площадка

При распарсивании документа JSON не все свойства, определенные в struct, должны присутствовать в документе JSON. В вашем примере вы могли бы определить следующую структуру:

type MyJson struct {
    Name string `json:"name"`
    Town string `json:"town"`
    Email string `json:"email"`
}

Когда вы используете эту структуру для размаршала документа JSON, в котором отсутствует одно или несколько этих свойств, они будут инициализированы нулевым значением соответствующего типа (пустой строкой для свойств string).


Альтернативно, вы можете использовать общий тип interface{} для разгруппировки и затем использовать утверждения типов. Это подробно описано в блог-посте "JSON и GO":

.
var jsonDocument interface{}

err := json.Unmarshal(jsonString, &jsonDocument)
map := jsonDocument.(map[string]interface{})
town := map["town"].(string);

2022 WebDevInsider