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

Go语言中如何处理嵌套非结构化JSON并提取指定数据

Go语言从非结构化JSON中提取特定数据

需求说明

给定一段非结构化JSON数据,要求当Material字段下的Foo1为非空数组时,提取Material->Foo1中的method值,同时获取classifications->Foo1中的desc值。

原代码问题

你提供的示例代码中,结构体New仅定义了Desc字段,无法适配Material下的数组结构;且用map[string]map[string]New接收整个JSON也不合适,因为Material的字段值是数组而非New类型结构体。

解决方案

由于JSON结构非结构化,字段值类型不统一(对象、数组并存),使用map[string]interface{}解析更灵活,通过类型断言逐层提取目标数据,同时加入格式校验保证代码健壮性。

完整实现代码

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	bJson := `{ 
                "classifications": { 
                    "Foo1": { 
                        "desc": "It may be possible.", 
                        "sol": "The backups.", 
                        "ref": { 
                            "Sensitive Information": "https://www.sensitive_Information.html", 
                            "Control Sphere": "https://ww.example.org/data.html" 
                        }
                    },
                    "Bar1": { 
                        "desc": "The target", 
                        "sol": "should be used.", 
                        "ref": { "ABC: Srgery": "https://www.orp.org/" } 
                    }
                }, 
                "Material": { 
                    "Backup file": [],
                    "Foo1": [ { 
                        "method": "GET", 
                        "info": "It is not set", 
                        "level": 1, 
                        "parameter": "", 
                        "referer": "", 
                        "module": "diq", 
                        "curl_command": "curl \"https://example.com/\"", 
                        "wsg": [ "CONF-12", "O-Policy" ] 
                    }],
                    "foo2": [],
                    "Bar1": []
                },
                "anomalies": { "Server Error": [], "Resource consumption": [] }, 
                "additionals": { "web technology": [], "Methods": [] }, 
                "infos": { "url": "https://example.com/", "date": "Thu, 08 Dec 2022 06:52:04 +0000"}
            }`

	var data map[string]interface{}
	if err := json.Unmarshal([]byte(bJson), &data); err != nil {
		fmt.Println("JSON解析失败:", err)
		return
	}

	// 提取Material下的Foo1并检查是否非空
	material, ok := data["Material"].(map[string]interface{})
	if !ok {
		fmt.Println("Material字段格式不符合预期")
		return
	}

	foo1Material, ok := material["Foo1"].([]interface{})
	if !ok || len(foo1Material) == 0 {
		fmt.Println("Material->Foo1为空或格式错误")
		return
	}

	// 提取method值
	foo1Item, ok := foo1Material[0].(map[string]interface{})
	if !ok {
		fmt.Println("Material->Foo1元素格式错误")
		return
	}
	method, ok := foo1Item["method"].(string)
	if !ok {
		fmt.Println("method字段不存在或类型错误")
		return
	}

	// 提取classifications下Foo1的desc值
	classifications, ok := data["classifications"].(map[string]interface{})
	if !ok {
		fmt.Println("classifications字段格式不符合预期")
		return
	}

	foo1Class, ok := classifications["Foo1"].(map[string]interface{})
	if !ok {
		fmt.Println("classifications->Foo1格式错误")
		return
	}
	desc, ok := foo1Class["desc"].(string)
	if !ok {
		fmt.Println("desc字段不存在或类型错误")
		return
	}

	// 输出结果
	fmt.Printf("Method is %s\n", method)
	fmt.Printf("desc is %s\n", desc)
}

代码说明

  1. 用map[string]interface{}接收整个JSON,适配非结构化的多变结构
  2. 逐层进行类型断言,每一步都做格式校验,避免程序panic
  3. 先校验Material->Foo1是否为非空数组,再提取第一个元素的method
  4. 再提取classifications->Foo1中的desc值
  5. 加入错误处理,提升代码健壮性

预期输出

Method is GET
desc is It may be possible.

扩展说明

如果需要批量处理Material下所有非空的键(比如Bar1),可以遍历Material的键值对,逐个检查数组是否非空,再对应提取classifications中同名键的desc值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:40:28