JSONPathに基づくGolangJsonコンテンツの追加、削除、および変更

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

おすすめ

転載: juejin.im/post/7120503723205328926