英文:
Handling Nested Unstructured JSON in Go Lang
问题
我正在尝试理解如何在GoLang中访问非结构化JSON数据中的特定数据。我有以下JSON数据,我正在尝试访问Material下的"Foo1",当Foo1有一些数据时,而foo2是空的。当像Foo1这样的对象有数据时,我还需要从相同名称下的classifications部分读取数据。例如,当Material部分下的Foo1有数据时,我应该能够打印Material->Foo1下的method键值以及classification->Foo1下的desc。
期望的输出是如果Foo1不为空:
Method is GET
desc is It may be possible.
英文:
I'm trying to understand how can I access a particular data from an unstructured JSON data in GoLang. I've the following JSON and I'm trying to access "Foo1" under Material when Foo1 has some data unlike foo2 which is empty. When the object like Foo1 has data, I also need to read data from classifications section under the same name. For instance. as Foo1 under Material section has data, I should be already to print method key value under Material->Foo1 along with desc from classification -> Foo1.
package main
import (
"encoding/json"
"fmt"
)
type New struct {
Desc string `json:"desc"`
}
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 parsedData = make(map[string]map[string]New)
json.Unmarshal([]byte(bJson), &parsedData)
fmt.Println("output of parsedData - \n", parsedData["classifications"]["Foo1"].Desc)
//for _, v := range parsedData["Material"] {
// fmt.Println(v)
//}
}
Expected output is if Foo1 is not empty:
Method is GET
desc is It may be possible.
答案1
得分: 1
你可以将其解组为map[string]interface{}
变量,然后使用一系列类型断言来获取所需的信息,例如:
var parsedData = make(map[string]interface{})
json.Unmarshal([]byte(bJson), &parsedData)
fmt.Printf("Method is %s\n", parsedData["classifications"].
(map[string]interface{})["Material"].
(map[string]interface{})["Foo1"].
([]interface{})[0].
(map[string]interface{})["method"].(string))
上述代码将输出:
Method is GET
以下是完整可运行的代码版本:
package main
import (
"encoding/json"
"fmt"
)
type New struct {
Desc string `json:"desc"`
}
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 parsedData = make(map[string]interface{})
json.Unmarshal([]byte(bJson), &parsedData)
fmt.Printf("Method is %s\n", parsedData["classifications"].(map[string]interface{})["Material"].(map[string]interface{})["Foo1"].([]interface{})[0].(map[string]interface{})["method"].(string))
}
如果我构建这个代码:
go build -o example main.go
它会运行如下:
$ ./main
Method is GET
要检查一个值是否不存在或为空列表:
data := parsedData["classifications"].(map[string]interface{})["Material"].(map[string]interface{})
val, ok := data["foo2"]
if !ok {
panic("no key foo2 in map")
}
if count := len(val.([]interface{})); count == 0 {
fmt.Printf("foo2 is empty\n")
} else {
fmt.Printf("foo2 has %d items", count)
}
英文:
You can unmarshal it into a map[string]interface{}
variable and then use a series of type assertions to get the information you want, like:
var parsedData = make(map[string]interface{})
json.Unmarshal([]byte(bJson), &parsedData)
fmt.Printf("Method is %s\n", parsedData["classifications"].
(map[string]interface{})["Material"].
(map[string]interface{})["Foo1"].
([]interface{})[0].
(map[string]interface{})["method"].(string))
The above will output:
Method is GET
Here's the complete, runnable version of the code:
package main
import (
"encoding/json"
"fmt"
)
type New struct {
Desc string `json:"desc"`
}
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 parsedData = make(map[string]interface{})
json.Unmarshal([]byte(bJson), &parsedData)
fmt.Printf("Method is %s\n", parsedData["classifications"].(map[string]interface{})["Material"].(map[string]interface{})["Foo1"].([]interface{})[0].(map[string]interface{})["method"].(string))
}
If I build this:
go build -o example main.go
It runs like this:
$ ./main
Method is GET
To check if a value does not exist or is an empty list:
data := parsedData["classifications"].(map[string]interface{})["Material"].(map[string]interface{})
val, ok := data["foo2"]
if !ok {
panic("no key foo2 in map")
}
if count := len(val.([]interface{})); count == 0 {
fmt.Printf("foo2 is empty\n")
} else {
fmt.Printf("foo2 has %d items", count)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论