处理嵌套的非结构化 JSON 在 Go 语言中

huangapple go评论89阅读模式
英文:

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)
}

huangapple
  • 本文由 发表于 2022年12月11日 23:29:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/74762073.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定