Unmarshal nested JSON structure

First of all: Don't ignore errors returned by a function or method unless you have a very good reason to do so.

If you make the following change to the code:

err := json.Unmarshal([]byte(jStr), &cont)
if err != nil {
    fmt.Println(err)
}

You will see the error message telling you why the value is empty:

json: cannot unmarshal object into Go value of type string

Simply put: Key cannot be of type string, so you have to use a different type. You have several option on how to decode it depending on the characteristics of the Key value:

  • If the structure is static, use another struct to match this structure.
  • If the structure is dynamic, use interface{} (or map[string]interface{} if it is always of type JSON object)
  • If the value is not to be accessed, only to be used in later JSON encoding, or if the decoding is to be delayed, use json.RawMessage

Use nested structs in Go to match the nested structure in JSON.

Here's one example of how to handle your example JSON:

package main

import (
    "encoding/json"
    "fmt"
    "log"
)

func main() {
    jStr := `
    {
        "AAA": {
            "assdfdff": ["asdf"],
            "fdsfa": ["1231", "123"]
        }
    }
    `

    type Inner struct {
        Key2 []string `json:"assdfdff"`
        Key3 []string `json:"fdsfa"`
    }
    type Container struct {
        Key Inner `json:"AAA"`
    }
    var cont Container
    if err := json.Unmarshal([]byte(jStr), &cont); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%+v\n", cont)
}

playground link

You can also use an anonymous type for the inner struct:

type Container struct {
    Key struct {
        Key2 []string `json:"assdfdff"`
        Key3 []string `json:"fdsfa"`
    }  `json:"AAA"`
}

playground link

or both the outer and inner structs:

var cont struct {
    Key struct {
        Key2 []string `json:"assdfdff"`
        Key3 []string `json:"fdsfa"`
    } `json:"AAA"`
}

playground link

If you don't know the field names in the inner structure, then use a map:

type Container struct {
    Key map[string][]string `json:"AAA"`
}

http://play.golang.org/p/gwugHlCPLK

There are more options. Hopefully this gets you on the right track.

Tags:

Json

Go