本文概览:介绍了两个jsonpath的包,分别进行get和set操作
一、JsonPath语法
JSONPath 是查询 JSON 对象的元素的标准化方式。https://jsonpath.com/ 通过这个网站可以测试jsonpath。
$
表示文档的根元素@
表示文档的当前元素.node_name
或['node_name']
匹配下级节点[index]
检索数组中的元素[start:end:step]
支持数组切片语法*
作为通配符,匹配所有成员..
子递归通配符,匹配成员的所有子元素(<expr>)
使用表达式?(<boolean expr>)
进行数据筛选
二、读和写操作
-
json包括对象(map)和数组两大类,所以如下的jsonData 会有 []interface类型和map[string]interface{}两种类型
1 2 |
var jsonData interface{} json.Unmarshal([]byte(data), &jsonData) |
2.1 读操作
工具包:https://github.com/oliveagle/jsonpath
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package service import ( "encoding/json" "fmt" mdjsonpath "github.com/mdaverde/jsonpath" "github.com/oliveagle/jsonpath" "reflect" "testing" ) func TestParse(t *testing.T) { data := "{ \"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 } }, \"expensive\": 10 }" var jsonData interface{} json.Unmarshal([]byte(data), &jsonData) res, err := jsonpath.JsonPathLookup(jsonData, "$.store.book[0,1].price") if err != nil { fmt.Println(err) return } fmt.Print(res) } |
2.2 写操作
工具包:https://github.com/mdaverde/jsonpath
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
import ( "encoding/json" "fmt" mdjsonpath "github.com/mdaverde/jsonpath" "reflect" "testing" ) // https://github.com/mdaverde/jsonpath func TestSet(t *testing.T) { data := "{ \"stringvalue\": \"aa\", \"intvalue\": 123, \"arrayIntValue\": [123, 456], \"arrayStringValue\": [\"aa\", \"bb\"] }" var jsonData interface{} json.Unmarshal([]byte(data), &jsonData) // 1.int jsonPath := "$.intvalue" jsonPath = jsonPath[len("$."):] mdjsonpath.Set(jsonData, jsonPath, 44) fmt.Print(jsonData) // 2.string jsonPath = "$.stringvalue" jsonPath = jsonPath[len("$."):] mdjsonpath.Set(jsonData, jsonPath, "aa_v2") fmt.Print(jsonData) // 3.json jsonPath = "$.jsonvalue" jsonPath = jsonPath[len("$."):] inputStr := "{ \"te\": \"123\", \"td\": \"456\" }" var inputJson interface{} json.Unmarshal([]byte(inputStr), &inputJson) mdjsonpath.Set(jsonData, jsonPath, inputJson) fmt.Print(jsonData) // 4.arrayString fieldValue, err := jsonpath.JsonPathLookup(jsonData, "$.arrayStringValue") if err != nil { fmt.Println(err) return } if reflect.ValueOf(fieldValue).Kind() != reflect.Array && reflect.ValueOf(fieldValue).Kind() != reflect.Slice { fmt.Println("not array") return } newArrayValue := append(fieldValue.([]interface{}), "dd") jsonPath = "$.arrayStringValue" jsonPath = jsonPath[len("$."):] mdjsonpath.Set(jsonData, jsonPath, newArrayValue) fmt.Print(fieldValue) // 5.arrayInt fieldValue, err = jsonpath.JsonPathLookup(jsonData, "$.arrayIntValue") if err != nil { fmt.Println(err) return } if reflect.ValueOf(fieldValue).Kind() != reflect.Array && reflect.ValueOf(fieldValue).Kind() != reflect.Slice { fmt.Println("not array") return } newArrayValue = append(fieldValue.([]interface{}), 55) jsonPath = "$.arrayIntValue" jsonPath = jsonPath[len("$."):] mdjsonpath.Set(jsonData, jsonPath, newArrayValue) fmt.Print(fieldValue) } |
样例测试。输入信息如下
1 2 3 4 5 6 |
{ "stringvalue": "aa", "intvalue": 123, "arrayIntValue": [123, 456], "arrayStringValue": ["aa", "bb"] } |
功能 | 代码 | 样例结果 | ||||
字段覆盖字段-int |
|
|
||||
字段覆盖字段-string |
|
|
||||
字段覆盖字段-json |
|
|
||||
字段追加-string |
|
|
||||
字段追加-int |
|
|