Reputation: 33
what is the best practice to unmarshall a specific part of a large JSON with static property names in GO?
my JSON map looks like
{
"top_view" : {
"@self" : "https://generic.com",
"graph" : {
"nodes" : [ { } ],
"relations" : [ { } ]
},
"view_status" : {}
}
}
and I only need to retrieve the Nodes array
Here is what I got so far,
https://play.golang.org/p/btfRojEGqUu
I only know how to unmarshall the Nodes part, but I don't know how to tell Go to start unmarshalling only that object, so the code won't work if I feed the entire JSON tree. Please advise, thanks!
Upvotes: 1
Views: 1479
Reputation: 43
This is one way to do it: Define a struct that shows the path to the Node. You can skip the members in the JSON that are not interesting. For example:
type Whole struct {
TopView struct {
Self string `json:"@self"`
Graph struct {
Nodes []Node `json:"nodes"`
} `json:"graph"`
} `json:"top_view"`
}
Then marshal out the Node
var whole Whole
err := json.Unmarshal([]byte(jsonResp), &whole)
Here is the working code : https://play.golang.org/p/5WvPocce_vh
Upvotes: 1
Reputation: 550
You can unmarshall any JSON data without any concrete type defined in the go
code. An use type assertion
and type switch
to drill-down the data just unmarshlled.
Below is working example of your problem using above mentioned concepts. You may need to further refine this basis your requirement, but basic concept remains the same:
package main
import (
"encoding/json"
"fmt"
"log"
)
func main() {
jsonResponse := `{
"top_view" : {
"@self" : "https://generic.com",
"graph" : {
"nodes" : [ {
"@self" : "https://generic.com:443",
"id" : "1;;45d554600be28ee49c99d26e536225ea;;461ff354437881f6b5973d4af366b91c;;4c0f2cc8e29a4fe09240b2a0c311508d",
"ci" : {
"id" : "4c0f2cc8e29a4fe09240b2a0c311508d",
"name" : "NOICE",
"type" : "ci_collection",
"type_label" : "CiCollection",
"icon" : "/logical_group_32.svg"
},
"has_children" : true
}, {
"@self" : "https://generic.com:443hjkhk",
"id" : "1;;45d554600be28ee49c99d26e536225ea;;4e22910a478bf6939aed36fef22dc79e;;4a7788eeecbbeee3a8bb3189ba67f269",
"ci" : {
"id" : "4a7788eeecbbeee3a8bb3189ba67f269",
"name" : "NOTNOICE",
"type" : "ci_collection",
"type_label" : "CiCollection",
"icon" : "/logical_group_32.svg"
},
"has_children" : true
}, {
"@self" : "https://generic.com:443/fghfgh",
"id" : "1;;45d554600be28ee49c99d26e536225ea;;461ff354437881f6b5973d4af366b91c;;4c0f2cc8e29a4fe09240b2a0c311508d;;40b8b314821d01ac874f7209c228ab8f",
"ci" : {
"id" : "40b8b314821d01ac874f7209c228ab8f",
"name" : "NOICE",
"type" : "ci_collection",
"type_label" : "CiCollection",
"icon" : "/logical_group_32.svg"
},
"has_children" : true
}, {
"@self" : "https://generic.com:443/gfhgh",
"id" : "1;;45d554600be28ee49c99d26e536225ea;;4a208e0deee006668bb3cfab6541a869;;4bd30d48bc1c81b398e17435ba519f2d;;4a1c671cefd3b5b9931b4312382ff2e4",
"ci" : {
"id" : "4a1c671cefd3b5b9931b4312382ff2e4",
"name" : "AAA",
"type" : "ci_collection",
"type_label" : "CiCollection",
"icon" : "/logical_group_32.svg"
},
"has_children" : true
} ],
"relations" : [ { } ]
},
"view_status" : {}
}
}`
var res interface{}
err := json.Unmarshal([]byte(jsonResponse), &res)
if err != nil {
log.Fatal(err)
}
parseArbitoryJSONObject(res)
}
func parseArbitoryJSONObject(jsonObject interface{}) {
data := jsonObject.(map[string]interface{})
for k, v := range data {
switch val := v.(type) {
case string:
fmt.Println(k, "is string:", val)
case float64:
fmt.Println(k, "is float64", val)
case bool:
fmt.Println(k, "is boolean", val)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range val {
fmt.Println(i, u)
}
case map[string]interface{}:
fmt.Println(k, "is an map[string]interface{}:")
parseArbitoryJSONObject(val)
default:
fmt.Println(k, "is of a type I don't know how to handle")
}
}
}
Here the json.Unmarshal
is using empty interface
which can hold any value. And function parseArbitoryJSONObject()
is using type assertion
to facilitate value extraction from the unmarshlled data.
The type switch
is where you may need to further put or modify logic to get the desired item from the unmarshlled JSON object.
below is the go-playground code snippet link for your reference:
https://play.golang.org/p/VUJsSXxSfVG
Upvotes: -1