使用Go语言解析动态JSON格式
通常使用Golangencoding/json
标准库可以方便的编码/解析JSON数据,但是前提需要定义struct数据结构。特别是解析未知结构的JSON数据时,原有方法很难满足需求了,本文主要介绍动态解析JSON格式。
1、传统方法
比如User
数据结构如下:
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
在定义struct字段的时候,可以在字段后面添加tag,来控制encode/decode的过程:是否要 decode/encode 某个字段,JSON 中的字段名称是什么。字段名首字母控制字段的可见性,若要输出到JSON,首字母需要大写。
三种tag:-
:不要解析这个字段omitempty
:当字段为空(默认值)时,不要解析这个字段。比如 false、0、nil、长度为 0 的 array,map,slice,stringFieldName
:当解析 json 的时候,使用这个名字
举例来说吧:
// 解析的时候忽略该字段。默认情况下会解析这个字段,因为它是大写字母开头的
Field int `json:"-"`
// 解析(encode/decode) 的时候,使用 `other_name`,而不是 `Field`
Field int `json:"other_name"`
// 解析的时候使用 `other_name`,如果struct 中这个值为空,就忽略它
Field int `json:"other_name,omitempty"`
(1)encode
user := User{Name: "test", Age:23}
data, err := json.Marshal(user)
if err != nil {
fmt.Println(string(data))
}
data 就是 []byte 类型的数组,里面包含了解析为 JSON 之后的数据,可以使用string(data)转型为string。
(2)decode
要把JSON数据转换成Go类型的值(Decode),可以使用json.Unmarshal
。
var user User
err = json.Unmarshal(data, &user)
if err != nil {
fmt.Errorf("Can not decode data: %v\n", err)
}
2、动态解析
动态JSON结构未知,若使用前面方法需要事先定义数据结构,这与PHP/Python JSON处理非常不同。若不考虑性能,使用simplejson。
(1)simplejson
js, err := simplejson.NewJson([]byte(`{
"test": {
"string_array": ["asdf", "zxcv"],
"array": [1, "2", 3],
"arraywithsubs": [{"subkeyone": 1},
"bignum": 9223372036854775807,
"string": "simplejson",
"bool": true
}
}`))
if err != nil {
panic("json format error")
}
//获取某个字段值
s, err := js.Get("test").Get("string").String()
if err != nil {
panic(err)
}
fmt.Println(s)
//检查某个字段是否存在
_, ok := js.Get("test").CheckGet("string2")
if ok {
fmt.Println("存在!")
} else {
fmt.Println("不存在")
}
(2)interface
比如JSON有以下两种类型:
{"Type":"sound","Msg":{"Description":"dynamite","Authority":"the Bruce Dickinson"}}
{"Type":"cowbell","Msg":{"More":true}}
Msg
具体什么类型实现无法判断,Msg being a map[string]interface{}
:
type Envelope struct {
Type string
Msg interface{}
}
var env Envelope
if err := json.Unmarshal([]byte(input), &env); err != nil {
log.Fatal(err)
}
// for the love of Gopher DO NOT DO THIS
var desc string = env.Msg.(map[string]interface{})["description"].(string)
fmt.Println(desc)
参考:
https://godoc.org/github.com/bitly/go-simplejson
https://gocn.io/question/548
http://www.cnblogs.com/bvac/p/6293667.html
http://eagain.net/articles/go-dynamic-json/
评论已关闭