1.背景と目的
一般的なgo_jsonpathライブラリ(code.byted.org/temai/go\_j…
-
Get / MGet:指定されたノード要素値のクエリ
-
セット:ノード要素値の挿入を指定します
-
削除:指定されたノード要素の値を削除します
-
並べ替え:ノード要素のリストの並べ替えを指定します
2.Jsonライブラリのステータス
現在、いくつかの一般的なjson libを調査しましたが、理想的なものは見つかりませんでした。詳細は次のとおりです。
lib | 説明する | 例 |
---|---|---|
エンコーディング/json | Goの組み込みJSONエンコードおよびデコード(シリアル化および逆シリアル化) | - |
josephburnett / jd / lib | json diff | |
オリーブアグル/jsonpath | JSONPathに基づくノード要素クエリ | |
tidwall / sjson | カスタムドット構文に基づいて、指定されたノード要素の値を設定します。 | {"name":{"first": "Tom"、 "last": "Anderson"}、 "age":37、 "children":["Sara"、 "Alex"、 "Jack"]、"fav。 movie ":" Deer Hunter "、" friends ":[{"first ":" James "、" last ":" Murphy "}、{"first ":" Roger "、" last ":" Craig "}]} |
3. 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)
}