golang使用simplejson庫解析複雜json

cnblogs原創javascript

 

golang自帶的json解析庫encoding/json提供了json字符串到json對象的相互轉換,在json字符串比較簡單的狀況下仍是挺好用的,可是當json字符串比較複雜或者嵌套比較多的時候,就顯得力不從心了,不可能用encoding/json那種爲每一個嵌套字段定義一個struct類型的方式,這時候使用simplejson庫可以很方便的解析。例如,有這樣一個嵌套很深的json字符串,例子以下:java

{
	"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庫那就簡單多了,實例代碼以下:git

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)
			}

		}
	}
}
相關文章
相關標籤/搜索