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

如何在嵌套结构中解析含已知与未知字段的JSON?

Go解析含已知和未知字段的嵌套JSON

解决方案

要同时解析JSON中已知字段和未知字段,需要为Event结构体自定义JSON反序列化逻辑,具体实现如下:

1. 定义结构体

调整Event结构体,用json:"-"标记X字段,避免默认解析处理,后续通过自定义方法填充:

type Request struct {
    Common CommonParams `json:"common"`
    Events []Event      `json:"events"`
}

type CommonParams struct {
    A string `json:"a"`
    B string `json:"b"`
}

type Event struct {
    C string                 `json:"c"`
    X map[string]interface{} `json:"-"` // 忽略默认解析,自行处理
}

2. 实现自定义反序列化方法

为Event实现json.Unmarshaler接口,先解析已知字段,再提取所有未知字段:

func (e *Event) UnmarshalJSON(data []byte) error {
    // 临时结构体用于提取已知的C字段
    type tempEvent struct {
        C string `json:"c"`
    }
    var temp tempEvent
    // 解析已知字段
    if err := json.Unmarshal(data, &temp); err != nil {
        return err
    }

    // 解析所有字段到map
    var allFields map[string]interface{}
    if err := json.Unmarshal(data, &allFields); err != nil {
        return err
    }

    // 赋值已知字段,删除map中的已知键,剩余即为未知字段
    e.C = temp.C
    delete(allFields, "c")
    e.X = allFields
    return nil
}

3. 完整解析示例

以下是完整的解析测试代码:

package main

import (
    "encoding/json"
    "fmt"
)

type Request struct {
    Common CommonParams `json:"common"`
    Events []Event      `json:"events"`
}

type CommonParams struct {
    A string `json:"a"`
    B string `json:"b"`
}

type Event struct {
    C string                 `json:"c"`
    X map[string]interface{} `json:"-"`
}

func (e *Event) UnmarshalJSON(data []byte) error {
    type tempEvent struct {
        C string `json:"c"`
    }
    var temp tempEvent
    if err := json.Unmarshal(data, &temp); err != nil {
        return err
    }

    var allFields map[string]interface{}
    if err := json.Unmarshal(data, &allFields); err != nil {
        return err
    }

    e.C = temp.C
    delete(allFields, "c")
    e.X = allFields
    return nil
}

func main() {
    jsonStr := `{
        "common": {
            "a": "xyz",
            "b": "qwe"
        },
        "events": [
            {
                "c": "lll",
                "?": "eee",
                "??": "ppp"
            }
        ]
    }`

    var req Request
    if err := json.Unmarshal([]byte(jsonStr), &req); err != nil {
        panic(err)
    }

    fmt.Printf("Common参数: %+v\n", req.Common)
    fmt.Printf("Event的C字段值: %s\n", req.Events[0].C)
    fmt.Printf("未知字段集合: %+v\n", req.Events[0].X)
}

原理说明

  • 自定义UnmarshalJSON方法通过两次解析JSON:第一次提取已知的C字段,第二次获取所有字段到map中。
  • 删除map中的已知字段键后,剩余的键值对就是JSON中的未知字段,最终赋值给X字段。
  • 这种方式既保留了已知字段的强类型特性,又能灵活接收所有未知字段,完美适配嵌套JSON的解析需求。

内容的提问来源于stack exchange,提问作者khateeb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 05:30:03