Golang中如何通过JSONPath表达式删除JSON中的指定键?
Go 基于JSONPath删除JSON匹配键的实现方案
Go标准库没有内置JSONPath的增删改能力,你可以用成熟的开源JSONPath解析库配合动态JSON结构操作实现需求,针对你给出的示例数据和$.phoneNumbers.*.type表达式,具体实现如下:
核心逻辑
- 把原始JSON反序列化为
interface{}类型的动态嵌套结构(本质是map[string]interface{}和[]interface{}的嵌套组合),支持动态增删键,不需要提前定义结构体 - 解析JSONPath表达式定位到所有待删除键的父节点:你给出的表达式匹配的是
phoneNumbers数组下所有元素的type键,父节点就是数组里的每一个对象 - 遍历所有父节点,调用Go内置的
delete函数移除指定键 - 把修改后的结构重新序列化为JSON即可
可运行示例代码
package main import ( "encoding/json" "fmt" "github.com/PaesslerAG/jsonpath" ) func main() { // 原始JSON字符串 raw := `{ "firstName": "John", "lastName": "doe", "age": 26, "address": { "streetAddress": "naist street", "city": "Nara", "postalCode": "630-0192" }, "phoneNumbers": [ { "type": "iPhone", "number": "0123-4567-8888" }, { "type": "home", "number": "0123-4567-8910" } ] }` // 反序列化为动态结构 var data interface{} if err := json.Unmarshal([]byte(raw), &data); err != nil { panic(err) } // 匹配所有待删除键的父节点:$.phoneNumbers.* 对应phoneNumbers数组的所有元素 parentNodes, err := jsonpath.Get("$.phoneNumbers.*", data) if err != nil { panic(err) } // 遍历父节点删除type键 nodeList, ok := parentNodes.([]interface{}) if !ok { panic("JSONPath匹配结果类型不符合预期") } for _, node := range nodeList { if obj, isMap := node.(map[string]interface{}); isMap { delete(obj, "type") } } // 序列化输出结果 output, err := json.MarshalIndent(data, "", " ") if err != nil { panic(err) } fmt.Println(string(output)) }
运行结果
执行后输出的JSON中,phoneNumbers数组下的两个对象都会移除type字段,其余字段保持不变。
通用场景说明
如果需要支持任意合法JSONPath表达式的删除逻辑,不需要手动拆分父路径,可以选择支持返回匹配节点完整路径的JSONPath库,遍历路径时自动回溯到父节点完成删除,注意做好类型断言的容错判断,避免嵌套结构类型不匹配触发panic。
内容的提问来源于stack exchange,提问作者wangchi0113
相关产品推荐
相关产品推荐

