如何用解组解析一个复杂的JSON? [英] How to parse a complicated JSON with Go unmarshal?

查看:110
本文介绍了如何用解组解析一个复杂的JSON?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标准包编码/ json 暴露 json.Unmarshal 函数来解析JSON。



可以解组JSON字符串一个预定义的 struct ,或者使用 interface {} 并迭代结果以获得意外的JSON数据结构。



也就是说,我无法正确解析复杂的JSON。有人可以告诉我如何做到这一点?

  {
k1:v1,
k2:v2,
k3:10,
结果:[
[
[v4,v5,{k11:v11 ,k22:v22}]
,...,
[v4,v5,{k33:v33,k44:v44}


$ v $



$ div class =h2_lin>解决方案

引用来自 JSON和Go


如果不知道这些数据的结构,我们可以使用Unmarshal将其解码为一个接口{}:



$ p
$ b $ =
$ k $ b $ = ,
result:[v4,12.3,{k11:v11,k22:v22}]
}`)
var f interface {}
err:= json.Unmarshal(b,& f)




此时,f中的Go值将是一个映射,其键值是字符串,其值本身是以空接口值存储的:



  f = map [string] interface {} {
k1:v1,
k3:10,
result:[] interface {} {
v4,
12.3,
map [string] interface {} {
k11:v11 ,
k22:v22,
},
},
}




要访问这些数据,我们可以使用类型断言来访问 f 的底层映射[string]接口{}:



  m:= f。(map [string] interface {}) 




然后,我们可以用范围语句迭代地图,并使用键入开关以访问其值作为具体的类型:



  for k,v:= range m {
switch vv:= v。(type){
case string:
fmt.Println(k,is string,vv)
case int:
fmt.Println(k,is int,vv)
case [ ] interface {}:
fmt.Println(k,是一个数组:)
for i,u:= range vv {
fmt.Println(i,u)
}
默认值:
fmt.Println(k,是我不知道如何处理的类型)
}
}




通过这种方式,您可以使用未知的JSON数据,同时还能享受类型安全的好处。


关于Go和JSON的更多信息可以在原始文章中找到。我稍微改变了代码片段,使其更加类似于问题中的JSON。


In go the standard package encoding/json exposes json.Unmarshal function to parse JSON.

It's possible to either unmarshal the JSON string in a predefined struct, or use the interface{} and iterate the result for unexpected JSON data structure.

That said, I can't parse complex JSON properly. Can someone tell me how to achieve this?

 {
     "k1" : "v1", 
     "k2" : "v2", 
     "k3" : 10, 
     "result" : [
                 [
                 ["v4", v5, {"k11" : "v11", "k22" : "v22"}]
                 , ... , 
                 ["v4", v5, {"k33" : "v33", "k44" : "v44"}
                 ]
                 ], 
                 "v3"
                ] 
}

解决方案

Citing from JSON and Go:

Without knowing this data's structure, we can decode it into an interface{} value with Unmarshal:

b := []byte(`{
   "k1" : "v1", 
   "k3" : 10,
   result:["v4",12.3,{"k11" : "v11", "k22" : "v22"}]
}`)
var f interface{}
err := json.Unmarshal(b, &f)

At this point the Go value in f would be a map whose keys are strings and whose values are themselves stored as empty interface values:

f = map[string]interface{}{
    "k1": "v1",
    "k3":  10,
    "result": []interface{}{
       "v4",
       12.3,
       map[string]interface{}{
           "k11":"v11",
           "k22":"v22",
       },
    },
}

To access this data we can use a type assertion to access f's underlying map[string]interface{}:

m := f.(map[string]interface{})

We can then iterate through the map with a range statement and use a type switch to access its values as their concrete types:

for k, v := range m {
    switch vv := v.(type) {
    case string:
        fmt.Println(k, "is string", vv)
    case int:
        fmt.Println(k, "is int", vv)
    case []interface{}:
        fmt.Println(k, "is an array:")
        for i, u := range vv {
            fmt.Println(i, u)
        }
    default:
        fmt.Println(k, "is of a type I don't know how to handle")
    }
}

In this way you can work with unknown JSON data while still enjoying the benefits of type safety.

More information about Go and JSON can be found in the original article. I changed the code snippets slightly to be more similar to the JSON in the question.

这篇关于如何用解组解析一个复杂的JSON?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆