You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言如何解析含数字索引键的JSON对象?

解决Go解析带数字索引键的嵌套JSON问题

问题原因

你原有的代码只解析出ManagedElement的空结构,是因为JSON里的ManagedElement节点是一个包含"0"、"1"键的对象,但你的XYZ结构体只有Value、Values、Parameters字段,无法映射这些数字索引的子节点,导致这部分数据丢失。

解决方案

给XYZ结构体添加自定义的UnmarshalJSON方法,让它能同时处理两种节点类型:

  1. 叶子节点:包含Value/Values/Parameters字段
  2. 容器节点:包含数字索引键的子节点

完整代码示例

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 07:27:04