Go语言如何解析含数字索引键的JSON对象?
解决Go解析带数字索引键的嵌套JSON问题
问题原因
你原有的代码只解析出ManagedElement的空结构,是因为JSON里的ManagedElement节点是一个包含"0"、"1"键的对象,但你的XYZ结构体只有Value、Values、Parameters字段,无法映射这些数字索引的子节点,导致这部分数据丢失。
解决方案
给XYZ结构体添加自定义的UnmarshalJSON方法,让它能同时处理两种节点类型:
- 叶子节点:包含
Value/Values/Parameters字段 - 容器节点:包含数字索引键的子节点
完整代码示例
package main import ( "encoding/json" "fmt" ) type XYZ struct { Value string Values []string Parameters map[string]XYZ // 存储"0""1"这类数字索引的子节点 Children map[string]XYZ } // 自定义JSON解析逻辑,兼容两种节点结构 func (x *XYZ) UnmarshalJSON(data []byte) error { // 先尝试解析成带Value/Parameters的常规节点 type tempXYZ struct { Value string Values []string Parameters map[string]XYZ } var temp tempXYZ if err := json.Unmarshal(data, &temp); err == nil { x.Value = temp.Value x.Values = temp.Values x.Parameters = temp.Parameters x.Children = nil return nil } // 解析失败则按子节点map处理 var children map[string]XYZ if err := json.Unmarshal(data, &children); err != nil { return err } x.Children = children x.Value = "" x.Values = nil x.Parameters = nil return nil } type Service struct { Parameters map[string]XYZ } func main() { jsont := []byte(`{"Parameters": {"ManagedElement":{"0":{"Parameters": {"Id": {"Value": "MEId1"},"GNBCUCPFunction": {"Parameters": {"Id": {"Value": "GNBCUCPId1"},"EP_NgC":{"Parameters": {"Id": {"Value": "EPNGCId1"},"attributes": {"Parameters": {"remoteAddress": {"Value": "0.0.0.0"},"localAddress": {"Parameters": {"ipAddress": {"Value": "0.0.0.0"},"vlanId": {"Value": "1"}}}}}}}}}},"1":{"Parameters": {"Id": {"Value": "MEId1"},"GNBCUCPFunction": {"Parameters": {"Id": {"Value": "GNBCUCPId1"},"EP_NgC":{"Parameters": {"Id": {"Value": "EPNGCId1"},"attributes": {"Parameters": {"remoteAddress": {"Value": "0.0.0.0"},"localAddress": {"Parameters": {"ipAddress": {"Value": "0.0.0.0"},"vlanId": {"Value": "1"}}}}}}}}}}}}}`) var jsonb Service err := json.Unmarshal(jsont, &jsonb) if err != nil { fmt.Println("解析错误:", err) return } // 示例:访问解析后的完整数据 managedElement := jsonb.Parameters["ManagedElement"] fmt.Println("ManagedElement下的0号节点数据:") fmt.Printf(" ME ID: %s\n", managedElement.Children["0"].Parameters["Id"].Value) fmt.Printf(" GNB CUCP ID: %s\n", managedElement.Children["0"].Parameters["GNBCUCPFunction"].Parameters["Id"].Value) fmt.Printf(" EP_NgC ID: %s\n", managedElement.Children["0"].Parameters["GNBCUCPFunction"].Parameters["EP_NgC"].Parameters["Id"].Value) fmt.Printf(" 远程地址: %s\n", managedElement.Children["0"].Parameters["GNBCUCPFunction"].Parameters["EP_NgC"].Parameters["attributes"].Parameters["remoteAddress"].Value) fmt.Printf(" 本地IP: %s\n", managedElement.Children["0"].Parameters["GNBCUCPFunction"].Parameters["EP_NgC"].Parameters["attributes"].Parameters["localAddress"].Parameters["ipAddress"].Value) fmt.Printf(" VLAN ID: %s\n", managedElement.Children["0"].Parameters["GNBCUCPFunction"].Parameters["EP_NgC"].Parameters["attributes"].Parameters["localAddress"].Parameters["vlanId"].Value) fmt.Println("\nManagedElement下的1号节点数据:") fmt.Printf(" ME ID: %s\n", managedElement.Children["1"].Parameters["Id"].Value) }
代码说明
- 自定义的
UnmarshalJSON方法会先尝试按常规节点解析,如果失败(说明是数字索引的容器节点),就把数据解析成子节点map存入Children字段。 - 这样就能完整保留JSON中所有层级的数据,包括数字索引的节点。
内容的提问来源于stack exchange,提问作者Vikram Hon
相关产品推荐
相关产品推荐

