I need to parse x-www-form-urlencoded
body with nested key-value to get JSON format.
I’m trying to parse an x-www-form-urlencoded
body with nested key-value pairs into a JSON format. I have used url.ParseQuery
and r.Form
, but neither of these have returned the expected result of:
{
"name": "abc",
"age": 12,
"notes": {
"key1": "value1",
"key2": "value2"
}
}
The input body is:
name=abc&age=12¬es[key1]=value1¬es[key2]=value2
The output of url.ParseQuery
and r.Form
is:
{
"name": "abc",
"age": 12,
"notes[key1]": "value1",
"notes[key2]": "value2"
}
The body may contain up to three levels of nested key-value pairs. How can I parse the x-www-form-urlencoded
body to get the desired JSON format?
To parse the x-www-form-urlencoded
body with nested key-value pairs into the desired JSON format, you can use the following code:
package main
import (
"encoding/json"
"fmt"
"net/url"
"strings"
)
func main() {
body := "name=abc&age=12¬es[key1]=value1¬es[key2]=value2"
data := make(map[string]interface{})
values, _ := url.ParseQuery(body)
for key, value := range values {
nestedKeys := strings.Split(key, "[")
lastKey := nestedKeys[len(nestedKeys)-1][:len(nestedKeys[len(nestedKeys)-1])-1]
if len(nestedKeys) > 1 {
current := data
for i := 0; i < len(nestedKeys)-1; i++ {
if _, ok := current[nestedKeys[i]]; !ok {
current[nestedKeys[i]] = make(map[string]interface{})
}
current = current[nestedKeys[i]].(map[string]interface{})
}
current[lastKey] = value[0]
} else {
data[lastKey] = value[0]
}
}
jsonData, _ := json.MarshalIndent(data, "", " ")
fmt.Println(string(jsonData))
}
This code will output the desired JSON format:
{
"name": "abc",
"age": "12",
"notes": {
"key1": "value1",
"key2": "value2"
}
}
The code splits each key by “[” to identify nested keys. It then iterates over the nested keys and creates nested maps accordingly. Finally, it assigns the corresponding value to the last key in the nested structure.
Note that the values are stored as strings in the resulting JSON since the input body contains only string values. If you want to parse values into their respective types, you can modify the code accordingly.