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

Amo*_*rni 29 json go

场景:
考虑以下是JSON:

{
   "Bangalore_City": "35_Temperature",
   "NewYork_City": "31_Temperature",
   "Copenhagen_City": "29_Temperature"
}
Run Code Online (Sandbox Code Playgroud)

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

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

问题:有没有人能找到这种JSON解析的解决方案?我试过go-simplejson,gabs和默认encoding/json但没有运气.

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

[{
   "City_Name":"Bangalore",
   "Temperature": "35"
},...]
Run Code Online (Sandbox Code Playgroud)

然后我可以定义 struct

type TempData struct {
  City_Name string
  Temperature  string
}
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 37

你可以解组map[string]string为例如:

m := map[string]string{}
err := json.Unmarshal([]byte(input), &m)
if err != nil {
    panic(err)
}
fmt.Println(m)
Run Code Online (Sandbox Code Playgroud)

输出(包裹):

map[Bangalore_City:35_Temperature NewYork_City:31_Temperature
    Copenhagen_City:29_Temperature]
Run Code Online (Sandbox Code Playgroud)

Go Playground尝试一下.

这样,无论键或值是什么,您都可以使用所有map可以打印或循环的对.

另请注意,虽然您的示例仅包含string值,但如果值类型不同(例如string,数字等),您可以使用interface{}值类型,在这种情况下,您的地图将是类型map[string]interface{}.

还要注意我创建了一个库来轻松使用这些动态对象,这些在这些情况下可能会有很大的帮助:github.com/icza/dyno.

  • 请注意,这仅在您确定json不包含任何非字符串值时才有效.否则你必须使用`map [string] interface {} {}` (8认同)
  • 这也假设结构只有一层深。例如,此代码不适用于第一层的文字和更深的 json。 (2认同)

val*_*ala 7

标准encoding/json适用于大多数用例,但与替代解决方案相比,它可能相当慢。如果您需要性能,请尝试使用fastjson。它可以解析任意 JSON,而无需创建与 JSON 模式匹配的结构或映射。

请参阅下面的示例代码。它遍历(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)
        })
    }
})
Run Code Online (Sandbox Code Playgroud)

  • 你应该提到你是你链接到的库的作者 (fastjson) (24认同)
  • 列出你是作者的好习惯,因为你可能偏向于你自己写的东西。 (11认同)
  • 当您碰巧提到那个库、包等时,注意到您是库、包等的作者是一种常见的做法。而且它很优雅。我不相信这是一个要求。 (5认同)
  • 事实上,这可能是因为没有说他写了“fastjson”而遭到否决,这是愚蠢的。我们都对自己的答案有偏见。他只是碰巧很久以前以一个非常受欢迎的图书馆的形式表达了他的答案……我们有一个投票系统来消除他的偏见风险。说你写了一个“非商业”库是一个很好的做法,但要投反对票是荒谬的。(假设这就是原因。) (3认同)

Lar*_*sen 6

只是添加一个关于如何解析任何有效 JSON 的一般答案;var m interface{}适用于所有类型。其中包括映射(OP 要求的)数组、字符串、数字和嵌套结构。

var m interface{}
err := json.Unmarshal([]byte(input), &m)
if err != nil {
    panic(err)
}
fmt.Println(m)
Run Code Online (Sandbox Code Playgroud)