golang使用simplejson库解析复杂json

cnblogs原创

 

golang自带的json解析库encoding/json提供了json字符串到json对象的相互转换,在json字符串比较简单的情况下还是挺好用的,但是当json字符串比较复杂或者嵌套比较多的时候,就显得力不从心了,不可能用encoding/json那种为每个嵌套字段定义一个struct类型的方式,这时候使用simplejson库能够很方便的解析。例如,有这样一个嵌套很深的json字符串,例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
    "rc": 0,
    "error": "Success",
    "type": "stats",
    "progress": 100,
    "job_status": "COMPLETED",
    "result": {
        "total_hits": 803254,
        "starttime": 1528434707000,
        "endtime": 1528434767000,
        "fields": [],
        "timeline": {
            "interval": 1000,
            "start_ts": 1528434707000,
            "end_ts": 1528434767000,
            "rows": [{
                "start_ts": 1528434707000,
                "end_ts": 1528434708000,
                "number": "x12887"
            }, {
                "start_ts": 1528434720000,
                "end_ts": 1528434721000,
                "number": "x13028"
            }, {
                "start_ts": 1528434721000,
                "end_ts": 1528434722000,
                "number": "x12975"
            }, {
                "start_ts": 1528434722000,
                "end_ts": 1528434723000,
                "number": "x12879"
            }, {
                "start_ts": 1528434723000,
                "end_ts": 1528434724000,
                "number": "x13989"
            }],
            "total": 803254
        },
        "total": 8
    }
}

  

  对于上面的这个json字符串,其嵌套很深,如果要一个一个去定义对应的struct结构,无疑是一件比较费力的事情,如果使用simplejson库那就简单多了,实例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package main
 
import (
    "encoding/json"
    "fmt"
    "reflect"
    "strconv"
 
    simplejson "github.com/bitly/go-simplejson"
)
 
var json_str string = `{"rc" : 0,
  "error" : "Success",
  "type" : "stats",
  "progress" : 100,
  "job_status" : "COMPLETED",
  "result" : {
    "total_hits" : 803254,
    "starttime" : 1528434707000,
    "endtime" : 1528434767000,
    "fields" : [ ],
    "timeline" : {
      "interval" : 1000,
      "start_ts" : 1528434707000,
      "end_ts" : 1528434767000,
      "rows" : [ {
        "start_ts" : 1528434707000,
        "end_ts" : 1528434708000,
        "number" : "x12887"
      }, {
        "start_ts" : 1528434720000,
        "end_ts" : 1528434721000,
        "number" : "x13028"
      }, {
        "start_ts" : 1528434721000,
        "end_ts" : 1528434722000,
        "number" : "x12975"
      }, {
        "start_ts" : 1528434722000,
        "end_ts" : 1528434723000,
        "number" : "x12879"
      }, {
        "start_ts" : 1528434723000,
        "end_ts" : 1528434724000,
        "number" : "x13989"
      } ],
      "total" : 803254
    },
      "total" : 8
  }
}`
 
func main() {
 
    res, err := simplejson.NewJson([]byte(json_str))
 
    if err != nil {
        fmt.Printf("%v\n", err)
        return
    }
 
    //获取json字符串中的 result 下的 timeline 下的 rows 数组
    rows, err := res.Get("result").Get("timeline").Get("rows").Array()
 
    //遍历rows数组
    for _, row := range rows {
        //对每个row获取其类型,每个row相当于 C++/Golang 中的map、Python中的dict
        //每个row对应一个map,该map类型为map[string]interface{},也即key为string类型,value是interface{}类型
        if each_map, ok := row.(map[string]interface{}); ok {
 
            //可以看到each_map["start_ts"]类型是json.Number
            //而json.Number是golang自带json库中decode.go文件中定义的: type Number string
            //因此json.Number实际上是个string类型
            fmt.Println(reflect.TypeOf(each_map["start_ts"]))
 
            if start_ts, ok := each_map["start_ts"].(json.Number); ok {
                start_ts_int, err := strconv.ParseInt(string(start_ts), 10, 0)
                if err == nil {
                    fmt.Println(start_ts_int)
                }
            }
 
            if number, ok := each_map["number"].(string); ok {
                fmt.Println(number)
            }
 
        }
    }
}

  

posted @   impluse  阅读(20300)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示