1. Background and Objectives
Try developing a generic go_jsonpath library ( code.byted.org/temai/go\_j…
-
Get/MGet: query for the specified node element value
-
Set: Specifies the insertion of the node element value
-
Delete: delete the specified node element value
-
Sort: Specifies the sorting of the list of node elements
2. Status of Json library
Investigating some common json libs at present, no ideal ones were found. The details are as follows:
lib | illustrate | example |
---|---|---|
encoding/json | Go's built-in JSON encoding and decoding (serialization and deserialization) | - |
josephburnett/jd/lib | json diff | |
oliveagle/jsonpath | Node element query based on JSONPath | |
tidwall / sjson | Based on the custom dot syntax, set the value of the specified node element. | { "name": {"first": "Tom", "last": "Anderson"}, "age":37, "children": ["Sara","Alex","Jack"], "fav.movie": "Deer Hunter", "friends": [ {"first": "James", "last": "Murphy"}, {"first": "Roger", "last": "Craig"} ] } |
Three. go_jsonpath
go_jsonpath(code.byted.org/temai/go\_j…
3.1 jsonpath介绍
JSONPath 之于 JSON,就如 XPath 之于 XML。JSONPath 可以方便对 JSON 数据结构进行内容提取(goessner.net/articles/Js…
比如,下面Json
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
对应的jsonpath:
3.2 规则引擎govaluate介绍
规则引擎govaluate与 JavaScript 中的eval功能类似,用于计算任意表达式的值,详细用法参考github.com/Knetic/gova…
func main() {
expr, _ := govaluate.NewEvaluableExpression("foo > 0")
parameters := make(map[string]interface{})
parameters["foo"] = -1
result, _ := expr.Evaluate(parameters)
fmt.Println(result)
expr, _ = govaluate.NewEvaluableExpression("(requests_made * requests_succeeded / 100) >= 90")
parameters = make(map[string]interface{})
parameters["requests_made"] = 100
parameters["requests_succeeded"] = 80
result, _ = expr.Evaluate(parameters)
fmt.Println(result)
expr, _ = govaluate.NewEvaluableExpression("(mem_used / total_mem) * 100")
parameters = make(map[string]interface{})
parameters["total_mem"] = 1024
parameters["mem_used"] = 512
result, _ = expr.Evaluate(parameters)
fmt.Println(result)
}
3.3 go_jsonpath介绍
- 接口介绍
方法 | 用法 | 说明 |
---|---|---|
get | Get(path string) (val interface{}, err error) | 获取指定jsonpath |
set | Set(path string, value interface{}) (err error) | 更改指定jsonpath,key不存在时自动创建 |
delete | Delete(path string) (err error) | 删除指定jsonpath |
extract | Extract(path string, extractType ExtractTypeEnum) (err error) | 将复杂jsonpath值(url/json等)展开成结构化数据 |
ab_delete | abDelete() (err error) | 两个结构相同json匹配某种规则时,删除指定jsonpath |
- 详细用法
比如,下面json
{
"promotions":[
{
"product_id":"123",
"type":1
},
{
"product_id":"456",
"type":2
}
],
"extra":{
"logid":"20000000000000000000000000"
},
"entries":[
{
"title":"咨询",
"type":1
},
{
"title":"订单",
"type":2
}
],
"status_code":0,
"status_msg":""
}
处理逻辑
func TestGoJsonPath_Executor(t *testing.T) {
ctx := context.Background()
jf, err := os.Open(FromJson)
if err != nil {
t.Fatal(err.Error())
}
jv, err := ioutil.ReadAll(jf)
if err != nil {
t.Fatal(err.Error())
}
h, err := executor.NewExecutor(ctx, string(jv))
if err != nil {
t.Fatal(err.Error())
}
// 1. Set,Get
_ = h.Set("$.promotions[0].product_id", "5")
val, _ := h.Get("$.promotions[0].product_id")
assert.Equal(t, val, "5")
// 2. Sort,MGet
_ = h.Sort("$.entries", "get([v1], 'type') > get([v2], 'type')")
_, vals := h.MGet("$.entries[*].type")
assert.Equal(t, vals[0].(float64) > vals[1].(float64), true)
// 3. Delete
val, _ = h.Get("$.extra.logid")
assert.Equal(t, val, "20000000000000000000000000")
_ = h.Delete("$.extra.logid")
val, _ = h.Get("$.extra.logid")
assert.Equal(t, val, nil)
}