tommyd456
tommyd456

Reputation: 10673

Accessing JSON properties when not using struct

I have some JSON and I need to be able to access the properties. As the JSON properties can vary I can't create a struct to unmarshal into.

Example

The JSON could be this:

{"name" : "John Doe", "email" : "[email protected]"}

or this:

{"town" : "Somewhere", "email" : "[email protected]"}

or anything else.

How can I access each of the properties?

Upvotes: 0

Views: 199

Answers (3)

helmbert
helmbert

Reputation: 37934

When unmarshalling a JSON document, not all properties that are defined in the struct need to be present in the JSON document. In your example, you could define the following struct:

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

When your use this struct to unmarshal a JSON document that has one or more of these properties missing, they will be initialized with the respective type's null value (an empty string for string properties).


Alternatively, you can use the generic interface{} type for unmarshalling and then use type assertions. This is documented in-depth in the blog post "JSON and GO":

var jsonDocument interface{}

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

Upvotes: 0

ruakh
ruakh

Reputation: 183201

You can unmarshal it into an interface{}. If you do that, json.Unmarshal will unmarshal a JSON object into a Go map.

For example:

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

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

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

See <http://blog.golang.org/json-and-go#TOC_5.> for a complete example.

Upvotes: 5

Elwinar
Elwinar

Reputation: 9499

If you just happen to have fields that may not be specified, you can unmarshal your input into a struct with pointer. If the field isn't present, the pointer will be 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)
}

Playground

If you really want something more flexible, you can also unmarshal your input into a 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)
}

Playground

Upvotes: 0

Related Questions