I'm trying to find a way to use one JSON string as a "template" of sorts to apply to another JSON string. For instance, if my template looks as follows:
{
"id": "1",
"options": {
"leatherseats": "1",
"sunroof": "1"
}
}
which I then apply to the following JSON string:
{
"id": "831",
"serial": "19226715",
"options": {
"leatherseats": "black",
"sunroof": "full",
"fluxcapacitor": "yes"
}
}
I'd like a resultant JSON string as follows:
{
"id": "831",
"options": {
"leatherseats": "black",
"sunroof": "full",
}
}
Unfortunately I can't rely on either the template nor the input to be of a fixed format so I can't marshall/unmarshall into defined interfaces.
I got as far as writing a recursive function that traverses the template to construct a slice of string with the name of each node that is to be included.
func traverseJSON(key string, value interface{}) []string {
var retval []string
unboxed, ok := value.(map[string]interface{})
if ok {
for newkey, newvalue := range unboxed {
retval = append(retval, recurse(fmt.Sprintf("%s.%s", key, newkey), newvalue)...)
}
} else {
retval = append(retval, fmt.Sprintf("%s", key))
}
return retval
}
I call this function as follows:
template := `my JSON template here`
var result map[string]interface{}
json.Unmarshal([]byte(template), &result)
var nodenames []string
nodenames = append(nodenames, traverseJSON("", result)...)
I was then going to write a second function that takes this slice of node names to construct a JSON string from the input JSON string but ran out of steam and started thinking that I might be on the wrong track anyway.
Any help on this would be appreciated.