如何在Golang中解析/ deserlize动态JSON

时间:2015-03-30 13:09:12

标签: json go

情境:
请考虑以下是JSON:

{
   "Bangalore_City": "35_Temperature",
   "NewYork_City": "31_Temperature",
   "Copenhagen_City": "29_Temperature"
}

如果您注意到,数据的结构使得没有硬编码密钥提及City / Temperature基本上只是值。

问题:我无法解析任何动态的JSON。

问题:有没有人能找到这种JSON解析的解决方案?我尝试了go-simplejsongabs&默认encoding/json但没有运气。

注意: 以上JSON仅用于示例。并且有很多应用程序正在使用当前的API,所以我不想改变数据的结构。我的意思是我不能改变如下:

[{
   "City_Name":"Bangalore",
   "Temperature": "35"
},...]

然后我可以定义struct

type TempData struct {
  City_Name string
  Temperature  string
}

4 个答案:

答案 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 结构的小工具”