I have a JSON structure such as:
{
"persons":[
{
"name":"mark",
"surname":"zuckerberg",
"data":[
{
"userid":"09210",
"username":"mark290",
"registered_date":"10-01-2017"
},
{
"userid":"092240",
"username":"mark291",
"registered_date":"11-01-2017"
}
]
},
{
"name":"bill",
"surname":"clinton",
"data":[
{
"userid":"0442340",
"username":"billy",
"registered_date":"10-01-2000"
},
{
"userid":"89472894",
"username":"billary",
"registered_date":"11-01-2015"
}
]
}
]
}
I need to fetch each username for each person. Currently, in Go, which I am a total newbie at, I can get only the single JSONS within "data", with this snippet:
j := []byte(data)
var f interface{}
err := json.Unmarshal(j, &f)
map := f.(map[string]interface{})
for _,item := range map["persons"].([]interface{}) {
fmt.Printf("%v", item.(map[string]interface{})["data"])
fmt.Println(err)
I struggle to understand how to dive within each JSON struct within data in order to get each key,value pair.
CodePudding user response:
You can define the accurate nested structure corresponding to the JSON
bytes, to Unmarshal
.
package main
import (
"encoding/json"
"fmt"
)
type Trunk struct {
Persons []Person `json:"persons"`
}
type Person struct {
Name string `json:"name"`
Surname string `json:"surname"`
Data []User `json:"data"`
}
type User struct {
Userid string `json:"userid"`
Username string `json:"username"`
Registered_date string `json:"registered_date"`
}
func main() {
rawstring := []byte(`
{
"persons":[
{
"name":"mark",
"surname":"zuckerberg",
"data":[
{
"userid":"09210",
"username":"mark290",
"registered_date":"10-01-2017"
},
{
"userid":"092240",
"username":"mark291",
"registered_date":"11-01-2017"
}
]
},
{
"name":"bill",
"surname":"clinton",
"data":[
{
"userid":"0442340",
"username":"billy",
"registered_date":"10-01-2000"
},
{
"userid":"89472894",
"username":"billary",
"registered_date":"11-01-2015"
}
]
}
]
}
`)
jsondata := Trunk{}
if err := json.Unmarshal(rawstring, &jsondata); err == nil {
fmt.Println(jsondata)
// print first username of first person
// fmt.Println(jsondata.Persons[0].Data[0].Username)
// print each username of each person
for _, person := range jsondata.Persons {
for _, d := range person.Data {
fmt.Println(d.Username)
}
}
} else {
fmt.Println("Unmarshal failed!")
}
}
Or use a more compact structure defination:
type Trunk struct {
Persons []struct {
Name string `json:"name"`
Surname string `json:"surname"`
Data []struct {
Userid string `json:"userid"`
Username string `json:"username"`
Registered_date string `json:"registered_date"`
} `json:"data"`
} `json:"persons"`
}
CodePudding user response:
If you want to use streaming approach you can try to Decoder to find "username" Token and get next Token with "value".
dec := json.NewDecoder(strings.NewReader(rawstring))
for {
t, err := dec.Token()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
if val, ok := t.(string); ok && val == "username" {
t, err := dec.Token()
if err == io.EOF {
break
}
fmt.Println(t)
}
}