1. 从string到json格式的golang对象
首先将合法的json格式string或者yaml格式string解析为golang对象
- json格式为:
import "encoding/json"
var json_data interface{}
json.Unmarshal([]byte(json_str), &json_data)
json_str
为合法的json格式字符串变量或常量
interface{}
「空接口」代表任意类型的对象
- yaml格式为:
import (
yaml "gopkg.in/yaml.v3"
)
var json_data interface{}
yaml.Unmarshal([]byte(yaml_str), &json_data)
yaml_str
为合法的yaml格式字符串变量或常量
2. 从golang对象中根据路径提取值
路径格式点分割的键,所以需要一个键是数字时转化为数组下标取值的操作
import "unicode"
func isdigit(s string) bool {
for _, r := range s {
if !unicode.IsDigit(r) {
return false
}
}
return true
}
定义一个函数递归根据路径选择值,注意没有异常处理
import "strconv"
func getIn(obj interface{}, path []string) interface{} {
if len(path) == 0 {
return obj
}
var key = path[0]
if isdigit(key) {
i, _ := strconv.ParseInt(key, 10, 32)
t := obj.([]interface{})
return getIn(t[i], path[1:])
} else {
t := obj.(map[string]interface{})
return getIn(t[key], path[1:])
}
}
定义一个入口函数,键使用字符串形式传递
func jsonGet(json_obj interface{}, key string) interface{} {
if key == "" {
return json_obj
}
return getIn(json_obj, strings.Split(key, "."))
}
以下为main函数,使用实例
func main() {
var json_str string = `{
"name": {"first": "Tom", "last": "Anderson"},
"age":37,
"children": ["Sara","Alex","Jack"],
"fav.movie": "Deer Hunter",
"friends": [
{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
{"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
{"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
]
}
`
var json_data interface{}
json.Unmarshal([]byte(json_str), &json_data)
fmt.Println(jsonGet(json_data, "name.last"))
fmt.Println(jsonGet(json_data, "friends.1.nets.1"))
}
3.完整代码
// main.go
package main
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"unicode"
)
func isdigit(s string) bool {
for _, r := range s {
if !unicode.IsDigit(r) {
return false
}
}
return true
}
func getIn(obj interface{}, path []string) interface{} {
if len(path) == 0 {
return obj
}
var key = path[0]
if isdigit(key) {
i, _ := strconv.ParseInt(key, 10, 32)
t := obj.([]interface{})
return getIn(t[i], path[1:])
} else {
t := obj.(map[string]interface{})
return getIn(t[key], path[1:])
}
}
func jsonGet(json_obj interface{}, key string) interface{} {
if key == "" {
return json_obj
}
return getIn(json_obj, strings.Split(key, "."))
}
func main() {
var json_str string = `{
"name": {"first": "Tom", "last": "Anderson"},
"age":37,
"children": ["Sara","Alex","Jack"],
"fav.movie": "Deer Hunter",
"friends": [
{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
{"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
{"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
]
}
`
var json_data interface{}
json.Unmarshal([]byte(json_str), &json_data)
fmt.Println(jsonGet(json_data, "name.last"))
fmt.Println(jsonGet(json_data, "friends.1.nets.1"))
}
- 运行
$ go run main.go
Anderson
tw
更多介绍
有很多开源库也可以处理类似自由结构的json数据,下面列几个供参考
网友评论