Golang中如何遍历未知嵌套深度的JSON结构体
Golang 遍历未知嵌套深度JSON的实现方案
这个需求完全可以实现,不需要提前定义对应JSON的结构体,通过动态解析+递归遍历即可拿到所有底层叶子节点的键值对。
实现思路
- 不使用固定结构体反序列化,直接将JSON内容反序列化到
interface{}类型,Golang的json包会自动将JSON对象转为map[string]interface{},JSON数组转为[]interface{},基础类型直接映射为对应值。 - 编写递归函数判断当前值的类型:
- 若为
map[string]interface{},遍历所有键值对,将当前键拼接入路径后递归处理值 - 若为
[]interface{},遍历所有数组元素,拼接下标到路径后递归处理值 - 若为其他基础类型,即为底层叶子节点,直接输出对应键值即可
- 若为
完整示例代码
package main import ( "encoding/json" "fmt" ) // prefix为当前键的全路径,v为当前待遍历的值 func traverse(prefix string, v interface{}) { switch val := v.(type) { case map[string]interface{}: for k, item := range val { curKey := k if prefix != "" { curKey = prefix + "." + k } traverse(curKey, item) } case []interface{}: for idx, item := range val { curKey := fmt.Sprintf("%s[%d]", prefix, idx) traverse(curKey, item) } default: // 此处可根据需求调整输出,仅要底层键名可直接取curKey的最后一段 fmt.Printf("%q: %v\n", prefix, val) } } func main() { // 示例JSON rawJSON := `{ "informations": { "available": false, "provide": { "informations": { "customer": { "type": "foo", "address": { "name": "foo", "street": "foo", "zipcode": "123", "city": "foo" } } } } } }` var data interface{} if err := json.Unmarshal([]byte(rawJSON), &data); err != nil { panic(err) } traverse("", data) }
运行输出
"informations.available": false "informations.provide.informations.customer.type": foo "informations.provide.informations.customer.address.name": foo "informations.provide.informations.customer.address.street": foo "informations.provide.informations.customer.address.zipcode": 123 "informations.provide.informations.customer.address.city": foo
注意事项
- 默认反序列化的数字类型为
float64,如果需要转成整数可自行添加类型判断处理 - 若存在重名的底层键,建议保留完整键路径避免内容混淆
内容的提问来源于stack exchange,提问作者Markus Bach
相关产品推荐
相关产品推荐

