Golang 解组嵌套中的特定对象 JSON
Golang Unmarshall specific object in nested JSON
在 GO 中使用静态 属性 名称解组大型 JSON 的特定部分的最佳做法是什么?
我的JSON地图看起来像
{
"top_view" : {
"@self" : "https://generic.com",
"graph" : {
"nodes" : [ { } ],
"relations" : [ { } ]
},
"view_status" : {}
}
}
我只需要检索节点数组
这是我目前得到的,
https://play.golang.org/p/btfRojEGqUu
我只知道如何解组节点部分,但我不知道如何告诉 Go 开始只解组那个对象,所以如果我提供整个 JSON 树,代码将无法工作.
请指教,谢谢!
您可以解组任何 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",
"type" : "ci_collection",
"type_label" : "CiCollection",
"icon" : "/logical_group_32.svg"
},
"has_children" : true
}, {
"@self" : "https://generic.com:443/fghfgh",
"id" : "1;;45d554600be28ee49c99d26e536225ea;;461ff354437881f6b5973d4af366b91c;;4c0f2cc8e29a4fe09240b2a0c311508d;;40b8b314821d01ac874f7209c228ab8f",
"ci" : {
"id" : "40b8b314821d01ac874f7209c228ab8f",
"name" : "NOICE",
"type" : "ci_collection",
"type_label" : "CiCollection",
"icon" : "/logical_group_32.svg"
},
"has_children" : true
}, {
"@self" : "https://generic.com:443/gfhgh",
"id" : "1;;45d554600be28ee49c99d26e536225ea;;4a208e0deee006668bb3cfab6541a869;;4bd30d48bc1c81b398e17435ba519f2d;;4a1c671cefd3b5b9931b4312382ff2e4",
"ci" : {
"id" : "4a1c671cefd3b5b9931b4312382ff2e4",
"name" : "AAA",
"type" : "ci_collection",
"type_label" : "CiCollection",
"icon" : "/logical_group_32.svg"
},
"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 代码片段link供您参考:
这是一种方法:
定义一个显示节点路径的结构。您可以跳过 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)
在 GO 中使用静态 属性 名称解组大型 JSON 的特定部分的最佳做法是什么?
我的JSON地图看起来像
{
"top_view" : {
"@self" : "https://generic.com",
"graph" : {
"nodes" : [ { } ],
"relations" : [ { } ]
},
"view_status" : {}
}
}
我只需要检索节点数组
这是我目前得到的,
https://play.golang.org/p/btfRojEGqUu
我只知道如何解组节点部分,但我不知道如何告诉 Go 开始只解组那个对象,所以如果我提供整个 JSON 树,代码将无法工作. 请指教,谢谢!
您可以解组任何 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",
"type" : "ci_collection",
"type_label" : "CiCollection",
"icon" : "/logical_group_32.svg"
},
"has_children" : true
}, {
"@self" : "https://generic.com:443/fghfgh",
"id" : "1;;45d554600be28ee49c99d26e536225ea;;461ff354437881f6b5973d4af366b91c;;4c0f2cc8e29a4fe09240b2a0c311508d;;40b8b314821d01ac874f7209c228ab8f",
"ci" : {
"id" : "40b8b314821d01ac874f7209c228ab8f",
"name" : "NOICE",
"type" : "ci_collection",
"type_label" : "CiCollection",
"icon" : "/logical_group_32.svg"
},
"has_children" : true
}, {
"@self" : "https://generic.com:443/gfhgh",
"id" : "1;;45d554600be28ee49c99d26e536225ea;;4a208e0deee006668bb3cfab6541a869;;4bd30d48bc1c81b398e17435ba519f2d;;4a1c671cefd3b5b9931b4312382ff2e4",
"ci" : {
"id" : "4a1c671cefd3b5b9931b4312382ff2e4",
"name" : "AAA",
"type" : "ci_collection",
"type_label" : "CiCollection",
"icon" : "/logical_group_32.svg"
},
"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 代码片段link供您参考:
这是一种方法: 定义一个显示节点路径的结构。您可以跳过 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)