如何解决嵌套 JSON 中的 Golang Unmarshall 特定对象
在 GO 中使用静态属性名称解组大型 JSON 的特定部分的最佳实践是什么?
我的 JSON 映射看起来像
{
"top_view" : {
"@self" : "https://generic.com","graph" : {
"nodes" : [ { } ],"relations" : [ { } ]
},"view_status" : {}
}
}
而我只需要检索 Nodes 数组
这是我目前得到的,
https://play.golang.org/p/btfRojEGqUu
我只知道如何解组 Nodes 部分,但我不知道如何告诉 Go 开始仅解组该对象,因此如果我提供整个 JSON 树,代码将不起作用。 请指教,谢谢!
解决方法
这是一种方法: 定义一个显示节点路径的结构体。您可以跳过 JSON 中不感兴趣的成员。例如:
type Whole struct {
TopView struct {
Self string `json:"@self"`
Graph struct {
Nodes []Node `json:"nodes"`
} `json:"graph"`
} `json:"top_view"`
}
然后编组出节点
var whole Whole
err := json.Unmarshal([]byte(jsonResp),&whole)
这是工作代码: https://play.golang.org/p/5WvPocce_vh
,您可以解组任何 JSON 数据,而无需在 go
代码中定义任何具体类型。使用 type assertion
和 type switch
深入分析刚刚解组的数据。
以下是使用上述概念的问题的工作示例。您可能需要在此基础上进一步细化您的要求,但基本概念保持不变:
package main
import (
"encoding/json"
"fmt"
"log"
)
func main() {
jsonResponse := `{
"top_view" : {
"@self" : "https://generic.com","graph" : {
"nodes" : [ {
"@self" : "https://generic.com:443","id" : "1;;45d554600be28ee49c99d26e536225ea;;461ff354437881f6b5973d4af366b91c;;4c0f2cc8e29a4fe09240b2a0c311508d","ci" : {
"id" : "4c0f2cc8e29a4fe09240b2a0c311508d","name" : "NOICE","type" : "ci_collection","type_label" : "CiCollection","icon" : "/logical_group_32.svg"
},"has_children" : true
},{
"@self" : "https://generic.com:443hjkhk","id" : "1;;45d554600be28ee49c99d26e536225ea;;4e22910a478bf6939aed36fef22dc79e;;4a7788eeecbbeee3a8bb3189ba67f269","ci" : {
"id" : "4a7788eeecbbeee3a8bb3189ba67f269","name" : "NOTNOICE",{
"@self" : "https://generic.com:443/fghfgh","id" : "1;;45d554600be28ee49c99d26e536225ea;;461ff354437881f6b5973d4af366b91c;;4c0f2cc8e29a4fe09240b2a0c311508d;;40b8b314821d01ac874f7209c228ab8f","ci" : {
"id" : "40b8b314821d01ac874f7209c228ab8f",{
"@self" : "https://generic.com:443/gfhgh","id" : "1;;45d554600be28ee49c99d26e536225ea;;4a208e0deee006668bb3cfab6541a869;;4bd30d48bc1c81b398e17435ba519f2d;;4a1c671cefd3b5b9931b4312382ff2e4","ci" : {
"id" : "4a1c671cefd3b5b9931b4312382ff2e4","name" : "AAA","has_children" : true
} ],"relations" : [ { } ]
},"view_status" : {}
}
}`
var res interface{}
err := json.Unmarshal([]byte(jsonResponse),&res)
if err != nil {
log.Fatal(err)
}
parseArbitoryJSONObject(res)
}
func parseArbitoryJSONObject(jsonObject interface{}) {
data := jsonObject.(map[string]interface{})
for k,v := range data {
switch val := v.(type) {
case string:
fmt.Println(k,"is string:",val)
case float64:
fmt.Println(k,"is float64",val)
case bool:
fmt.Println(k,"is boolean",val)
case []interface{}:
fmt.Println(k,"is an array:")
for i,u := range val {
fmt.Println(i,u)
}
case map[string]interface{}:
fmt.Println(k,"is an map[string]interface{}:")
parseArbitoryJSONObject(val)
default:
fmt.Println(k,"is of a type I don't know how to handle")
}
}
}
这里的 json.Unmarshal
使用的是 empty interface
,它可以保存任何值。并且函数 parseArbitoryJSONObject()
使用 type assertion
来促进从未编组数据中提取值。
type switch
是您可能需要进一步放置或修改逻辑以从未编组的 JSON 对象中获取所需项目的地方。
以下是 go-playground 代码片段链接,供您参考:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。