如何解析/反序列化动态 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29347092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to parse/deserialize dynamic JSON
提问by Amol M Kulkarni
Scenario:
Consider the following is the JSON :
场景:
考虑以下是 JSON :
{
"Bangalore_City": "35_Temperature",
"NewYork_City": "31_Temperature",
"Copenhagen_City": "29_Temperature"
}
If you notice, the data is structured in such a way that there is no hard-coded keys mentioning City/Temperatureits basically just values.
如果您注意到,数据的结构方式没有硬编码键提及City/Temperature它基本上只是值。
Issue:I am not able to parse any JSON which is dynamic.
问题:我无法解析任何动态的 JSON。
Question:Could anyone have found solution for this kind of JSON parsing? I tried go-simplejson, gabs& default encoding/jsonbut no luck.
问题:有人能找到这种 JSON 解析的解决方案吗?我试过go-simplejson,gabs& defaultencoding/json但没有运气。
Note:The above JSON is just for sample. And there are lot of applications which are using the current API, So I do not want to change how the data is structured. I mean I can't change to something as follows:
注意:以上 JSON 仅用于示例。并且有很多应用程序都在使用当前的 API,所以我不想改变数据的结构。我的意思是我不能更改为以下内容:
[{
"City_Name":"Bangalore",
"Temperature": "35"
},...]
Then I can define struct
然后我可以定义 struct
type TempData struct {
City_Name string
Temperature string
}
回答by icza
You can unmarshal into a map[string]stringfor example:
您可以解组map[string]string为例如:
m := map[string]string{}
err := json.Unmarshal([]byte(input), &m)
if err != nil {
panic(err)
}
fmt.Println(m)
Output (wrapped):
输出(包装):
map[Bangalore_City:35_Temperature NewYork_City:31_Temperature
Copenhagen_City:29_Temperature]
Try it on the Go Playground.
在Go Playground上试一试。
This way no matter what the keys or values are, you will have all pairs in a mapwhich you can print or loop over.
这样,无论键或值是什么,您都将拥有map可以打印或循环的所有对。
Also note that although your example contained only stringvalues, but if the value type is varying (e.g. string, numbers etc.), you may use interface{}for the value type, in which case your map would be of type map[string]interface{}.
另请注意,虽然您的示例仅包含string值,但如果值类型是变化的(例如string,数字等),您可以使用interface{}值类型,在这种情况下,您的地图将是类型map[string]interface{}。
Also note that I created a library to easily work with such dynamic objects which may be a great help in these cases: github.com/icza/dyno.
另外请注意,我创建了一个库,这样的动态对象轻松工作,这可能是在这种情况下有很大的帮助:github.com/icza/dyno。
回答by valyala
Standard encoding/jsonis good for the majority of use cases, but it may be quite slow comparing to alternative solutions. If you need performance, try using fastjson. It parses arbitrary JSONs without the need for creating structs or maps matching the JSON schema.
标准encoding/json适用于大多数用例,但与替代解决方案相比,它可能相当慢。如果您需要性能,请尝试使用fastjson。它可以解析任意 JSON,而无需创建与 JSON 模式匹配的结构或映射。
See the example code below. It iterates over all the (key, value)pairs of the JSON object:
请参阅下面的示例代码。它遍历(key, value)JSON 对象的所有对:
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)
})
}
})

