情境:
请考虑以下是JSON:
{
"Bangalore_City": "35_Temperature",
"NewYork_City": "31_Temperature",
"Copenhagen_City": "29_Temperature"
}
如果您注意到,数据的结构使得没有硬编码密钥提及City
/ Temperature
基本上只是值。
问题:我无法解析任何动态的JSON。
问题:有没有人能找到这种JSON解析的解决方案?我尝试了go-simplejson,gabs&默认encoding/json
但没有运气。
注意: 以上JSON仅用于示例。并且有很多应用程序正在使用当前的API,所以我不想改变数据的结构。我的意思是我不能改变如下:
[{
"City_Name":"Bangalore",
"Temperature": "35"
},...]
然后我可以定义struct
type TempData struct {
City_Name string
Temperature string
}
答案 0 :(得分:33)
您可以解组为map[string]string
,例如:
m := map[string]string{}
err := json.Unmarshal([]byte(input), &m)
if err != nil {
panic(err)
}
fmt.Println(m)
输出(包裹):
map[Bangalore_City:35_Temperature NewYork_City:31_Temperature
Copenhagen_City:29_Temperature]
在Go Playground上尝试。
这种方式无论键或值是什么,您都可以使用map
中的所有对来打印或循环。
另请注意,尽管您的示例仅包含string
值,但如果值类型不同(例如string
,数字等),则可以使用interface{}
作为值类型,在这种情况下,您的地图的类型为map[string]interface{}
。
另请注意,我创建了一个库,可以轻松使用这些动态对象,在这些情况下可能会有很大的帮助:github.com/icza/dyno
。
答案 1 :(得分:2)
标准encoding/json
适用于大多数用例,但与其他解决方案相比可能相当慢。如果您需要演奏,请尝试使用fastjson。它解析任意JSON,而无需创建与JSON模式匹配的结构或映射。
请参阅下面的示例代码。它遍历JSON对象的所有(key, value)
对:
var p fastjson.Parser
v, err := p.Parse(input)
if err != nil {
log.Fatal(err)
}
// Visit all the items in the top object
v.GetObject().Visit(func(k []byte, v *fastjson.Value) {
fmt.Printf("key=%s, value=%s\n", k, v)
// for nested objects call Visit again
if string(k) == "nested" {
v.GetObject().Visit(func(k []byte, v *fastjson.Value) {
fmt.Printf("nested key=%s, value=%s\n", k, v)
})
}
})
答案 2 :(得分:1)
只需添加关于如何解析任何有效JSON的一般答案即可; var m interface{}
适用于所有类型。其中包括地图(OP要求的)数组,字符串,数字和嵌套结构。
var m interface{}
err := json.Unmarshal([]byte(input), &m)
if err != nil {
panic(err)
}
fmt.Println(m)
答案 3 :(得分:0)
还可以考虑使用 gabs 包 https://github.com/Jeffail/gabs
“Gabs 是一个在 Go 中处理动态或未知 JSON 结构的小工具”