Golang如何用静态结构体处理动态JSON数据

Golang如何用静态结构体处理动态JSON数据 我有类似这样的JSON数据:

{
"data" : {
"192.168.1.0" : {
"summary" : {
"health" :  "excellent"
}
} ,
"192.168.1.1" : {
"summary" : {
"health" :  "excellent"
}
}
}
}

我想为这个JSON数据创建一个结构体并处理动态类型。JSON数据会非常大,所以我不想使用接口来创建映射。

11 回复

非常感谢 @johandalabacka

更多关于Golang如何用静态结构体处理动态JSON数据的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


感谢 @inancgumus

这个JSON中哪些是动态的?哪些是固定的?

这里的"192.168.0.1"是动态的,可能是任意IP地址。 其余部分都是固定的

是的,这个解决方案比我的好多了。今天学到了新东西。非常感谢!

1 个赞

当然可以

slight_smile

你可以使用 https://mholt.github.io/json-to-go/

粘贴你的 JSON 然后重构 Golang 输出代码以满足你的需求。

正如所说,Map 应该很适合你的需求。

type Summary struct {
  Health string `json:"health"`
} `json:"summary"`

type Data map[string]Summary  `json:"data"`

所以你不需要使用空接口的映射,而是使用摘要的映射。

这确实有些棘手,但你可以尝试类似这样的方法:

func main() {
    fmt.Println("hello world")
}

你读取一些 JSON 令牌直到找到主机名,然后将后续内容解析为结构体。接着使用主机名和读取的结构体来构建包含主机和健康状态的新结构体。然后继续处理下一个。

如下所示:

package main

import (
	"encoding/json"
	"fmt"
)

var b = []byte(`
{
"data" : {
	"192.168.1.0" : {
		"summary" : {
			"health" : "excellent"
		}
	},
	"192.168.1.1" : {
		"summary" : {
			"health" : "excellent"
		}
	}
}
}`)

type Data struct {
    Ips map[string]struct{
	    Summary struct {
	        Health string `json:"health"`
	    } `json:"summary"`
    } `json:"data"`
}

func main() {
	data := Data{}

	_ = json.Unmarshal(b, &data)
	fmt.Printf("%#v\n", data)
}

查看:https://play.golang.org/p/19HNcB7KsuJ

可以使用json.RawMessage来延迟解析动态字段,同时保持静态结构体的主要框架。以下是处理这种动态JSON数据的示例:

package main

import (
    "encoding/json"
    "fmt"
    "log"
)

type Response struct {
    Data map[string]json.RawMessage `json:"data"`
}

type Summary struct {
    Health string `json:"health"`
}

func main() {
    jsonData := `{
        "data": {
            "192.168.1.0": {
                "summary": {
                    "health": "excellent"
                }
            },
            "192.168.1.1": {
                "summary": {
                    "health": "excellent"
                }
            }
        }
    }`

    var resp Response
    err := json.Unmarshal([]byte(jsonData), &resp)
    if err != nil {
        log.Fatal(err)
    }

    for ip, rawData := range resp.Data {
        var data struct {
            Summary Summary `json:"summary"`
        }
        
        err := json.Unmarshal(rawData, &data)
        if err != nil {
            log.Printf("Error parsing data for IP %s: %v", ip, err)
            continue
        }
        
        fmt.Printf("IP: %s, Health: %s\n", ip, data.Summary.Health)
    }
}

如果需要处理更复杂的嵌套结构,可以进一步分解:

type IPData struct {
    Summary Summary `json:"summary"`
}

func processDynamicJSON() {
    jsonData := `{
        "data": {
            "192.168.1.0": {"summary": {"health": "excellent"}},
            "192.168.1.1": {"summary": {"health": "good"}},
            "192.168.1.2": {"summary": {"health": "poor"}}
        }
    }`

    var resp Response
    if err := json.Unmarshal([]byte(jsonData), &resp); err != nil {
        log.Fatal(err)
    }

    results := make(map[string]string)
    for ip, rawMsg := range resp.Data {
        var ipData IPData
        if err := json.Unmarshal(rawMsg, &ipData); err != nil {
            continue
        }
        results[ip] = ipData.Summary.Health
    }

    fmt.Printf("Processed results: %+v\n", results)
}

这种方法避免了使用interface{},同时能够高效处理大型JSON数据中的动态键。

回到顶部