Reputation: 47
Unable to parse nested json into structs objects using go lang
I have a nested json string that I want to parse using struct in Go language. The json looks like this
{"action":"add","business":{"ListId":123,"ObjectTags":[{"tagCode":"csharp","tagName":"codename","tagValue":["2"],"tagType":3},{"tagCode":"goLang","tagName":"coding","tagValue":["3"],"tagType":3}]}}
I want to parse the json using GO language. The json has nested structure so I created the structs as mentioned in the below code
package main
import (
"encoding/json"
"fmt"
)
type ObjectTagsList struct {
tagCode string
tagName string
tagValue []string
}
type Model struct {
Action string `json:"action"`
Business struct {
ListId int64 `json:"ListId"`
ObjectTags []ObjectTagsList `json:"ObjectTags"`
} `json:"business"`
}
func main() {
Json := `{"action":"add","business":{"ListId":123,"ObjectTags":[{"tagCode":"csharp","tagName":"codename","tagValue":["2"],"tagType":3},{"tagCode":"goLang","tagName":"coding","tagValue":["3"],"tagType":3}]}}`
var model Model
json.Unmarshal([]byte(Json), &model)
fmt.Println(model.Action) // This prints correctly as "add"
fmt.Println(model.Business.ListId) // This prints correctly as "123"
fmt.Println(model.Business.ObjectTags) // THIS DOES NOT PRINT THE ObjectTags. Rather this prints the ObjectTags as "[{ []} { []}]"
}
I am unable to get the value of inner nested json into the structure.
I also tried unmarshalling the inner structure again as
var object []ObjectTagsList
//This gives error as cannot convert model.Business.ObjectTags (variable of type []ObjectTagsList) to type []byte
json.Unmarshal([]byte(model.Business.ObjectTags), &object)
//error as cannot convert model.Business.ObjectTags (variable of type []ObjectTagsList) to type []byte
fmt.Println(object)
And this gives me an error as cannot convert model.Business.ObjectTags (variable of type []ObjectTagsList) to type []byte.
How do I map this json into the struct ? I want to map this in such a way that I can use the objects like
model.Business.ObjectTags[0].tagCode //--> Should print/store "csharp"
model.Business.ObjectTags[0].tagValue[0] //--> Should print/store "2"
Please help
Upvotes: 1
Views: 441
Reputation: 311713
You can only marshal/unmarshal "exported" fields -- that is, fields that are accessible outside of the current package, which in Go means "fields that start with a capital letter". So if you were to modify your code to look like this:
package main
import (
"encoding/json"
"fmt"
)
type ObjectTagsList struct {
TagCode string
TagName string
TagValue []string
}
type Model struct {
Action string `json:"action"`
Business struct {
ListId int64 `json:"ListId"`
ObjectTags []ObjectTagsList `json:"ObjectTags"`
} `json:"business"`
}
func main() {
Json := `
{
"action": "add",
"business": {
"ListId": 123,
"ObjectTags": [
{
"tagCode": "csharp",
"tagName": "codename",
"tagValue": [
"2"
],
"tagType": 3
},
{
"tagCode": "goLang",
"tagName": "coding",
"tagValue": [
"3"
],
"tagType": 3
}
]
}
}
`
var model Model
json.Unmarshal([]byte(Json), &model)
fmt.Println(model.Action)
fmt.Println(model.Business.ListId)
fmt.Println(model.Business.ObjectTags)
}
You would get as output:
add
123
[{csharp codename [2]} {goLang coding [3]}]
Here we're taking advantage of the fact that the json
module will automatically map a key named tagCode
to a struct field named TagCode
, but really we should be explicit:
type ObjectTagsList struct {
TagCode string `json:"tagCode"`
TagName string `json:"tagName"`
TagValue []string `json:"tagValue"`
}
Upvotes: 2