You have quite some errors in your example (both in JSON text and source code). Let's fix them.
JSON text
First your JSON is not valid. Try this instead of yours:
{
"key1": "val1",
"key2": "val2",
"childStruct1" : {
"key3": "val3",
"key4": "val4"
},
"childStruct2" : {
"key5": "val5",
"key6": "val6"
}
}
Go type definitions
Second, your Go source defining your struct types has syntax errors.
Third, you have to export struct fields in order so the json
package can set their values. Try this instead of yours:
type ChildStruct1 struct {
Key3 string
Key4 string
}
type ChildStruct2 struct {
Key4 string
Key5 string
}
type MainStruct struct {
Key1 string
Key2 string
ChildStruct1 ChildStruct1
ChildStruct2 ChildStruct2
}
Code to parse the JSON text
And now on to the code to parse the JSON text. You can read the whole file into memory using ioutil.ReadFile()
, but often it is more efficient to not read the whole file but to "stream" it to a decoder (using the file as the input).
os.Open()
returns a *File
. It is not a []byte
, but it implements io.Reader
. So you can't pass it to json.Unmarshal()
. Instead create a json.Decoder
using json.NewDecoder()
which accepts an io.Reader
, so you can pass the opened file. And don't forget to close the opened file using File.Close()
, best to close it as a deferred statement (if opening it succeeds).
f, err := os.Open("jsonData.json")
if err != nil {
log.Panic(err)
}
defer f.Close()
var data MainStruct
err = json.NewDecoder(f).Decode(&data)
if err != nil {
log.Panic(err)
}
fmt.Println(data.Key1)
fmt.Printf("%+v", data)
(Note that I used log.Panic()
instead of log.Fatal()
as the latter calls os.Exit()
and hence our deferred function would not be called.)
Output:
val1
{Key1:val1 Key2:val2 ChildStruct1:{Key3:val3 Key4:val4} ChildStruct2:{Key4: Key5:val5}}
Modified version for the Go Playground
Here is a modified version that parses the JSON text from a constant defined in the source code, try it on the Go Playground:
var data MainStruct
err := json.Unmarshal([]byte(input), &data)
if err != nil {
log.Fatal(err)
}
fmt.Println(data.Key1)
fmt.Printf("%+v", data)
Final notes
Keys in the JSON text start with lowercase letters, struct field names in Go start with uppercase letters (needed in order to be exported), but the json
package is "clever" enough to match them. Should you use something different, you could use tags to specify how a struct field can be found in the json, e.g.
type ChildStruct1 struct {
Key3 string `json:"myKey3"`
Key4 string `json:"myKey4"`
}