diff --git a/gjson_hack/path.go b/gjson_hack/path.go index 10ef86c..496585f 100644 --- a/gjson_hack/path.go +++ b/gjson_hack/path.go @@ -66,9 +66,9 @@ func doExpandPath(gjsonResult gjson.Result, rootPath string, hasChildren bool, p gjsonResult.ForEach(func(key, value gjson.Result) bool { newRootPath := "" if len(rootPath) == 0 { - newRootPath = key.String() + newRootPath = getPathKey(key.String()) } else { - newRootPath = rootPath + "." + key.String() + newRootPath = rootPath + "." + getPathKey(key.String()) } if value.IsArray() || value.IsObject() { if !pathOption.OnlyFinalPath { @@ -125,9 +125,35 @@ func doExpandPath(gjsonResult gjson.Result, rootPath string, hasChildren bool, p return } +// getPathKey ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 20:54 2024/12/4 +func getPathKey(key string) string { + if !strings.Contains(key, ".") { + // 非特殊key + return key + } + if IsSpecialKey(key) { + // 已经是special key + return key + } + return SpecialKeyStart + key + SpecialKeyEnd +} + +// IsArrayItemPath 是否为数组子项路径 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 15:49 2024/12/5 +func IsArrayItemPath(path string) bool { + return strings.Contains(path, ArrayIdxTpl) +} + // ExpandArrayPath 根据真实数据展开数组路径 // -// 路径中若是包含 {{idx}} 占位符, 说明是需要展开的数组, 根据数组的时机数据, 进行数组的逐级展开 +// 路径中若是包含 {{idx}} 占位符, 说明是需要展开的数组, 根据数组的实际数据, 进行数组的逐级展开 // // Author : go_developer@163.com<白茶清欢> // @@ -145,7 +171,7 @@ func ExpandArrayPath(jsonStr string, pathConfig string, mapConfig string, expend if len(mapConfig) == 0 { mapConfig = pathConfig } - if !strings.Contains(pathConfig, ArrayIdxTpl) { + if !IsArrayItemPath(pathConfig) { // 不是数组模板配置, 无需展开 expendArrayResult.PathList = append(expendArrayResult.PathList, pathConfig) expendArrayResult.PathMap[pathConfig] = mapConfig @@ -163,7 +189,7 @@ func ExpandArrayPath(jsonStr string, pathConfig string, mapConfig string, expend return errors.New("mapConfig depth not equal pathConfig deep") } - valueResult := gjson.Parse(jsonStr).Get(pathConfigArr[0]) + valueResult := Get(gjson.Parse(jsonStr), pathConfigArr[0]) if !valueResult.Exists() { // 路径不存在, 无需设置具体值 return nil @@ -260,11 +286,11 @@ func Get(gjsonResult gjson.Result, path string) gjson.Result { return gjsonResult } if !gjsonResult.IsObject() && !gjsonResult.IsArray() { - return gjsonResult + return gjsonResult.Get(path) } if !IsSpecialPath(path) { // 不是特殊路径 - return gjsonResult + return gjsonResult.Get(path) } pathArr := strings.Split(path, ".") normalPathList := make([]string, 0) diff --git a/gjson_hack/path_test.go b/gjson_hack/path_test.go index 0d22ce4..41b4914 100644 --- a/gjson_hack/path_test.go +++ b/gjson_hack/path_test.go @@ -12,8 +12,6 @@ import ( "fmt" "testing" - "github.com/tidwall/sjson" - "github.com/tidwall/gjson" ) @@ -136,13 +134,14 @@ func TestPathOnlyFinallyPathWithUnfoldArray(t *testing.T) { func TestExpandArrayPath(t *testing.T) { mapData := map[string]any{ "person_list": []map[string]any{ - {"name": "zhang", "age": 10}, - {"name": "li", "age": 20}, - {"name": "wang", "age": 30}, + {"name": "zhang", "age": 10, "a.b": "people_name"}, + {"name": "li", "age": 20, "a.b": "people_name"}, + {"name": "wang", "age": 30, "a.b": "people_name"}, }, "company_info": map[string]any{ - "address": "Beijing", - "email": "xxx@xxx.com", + "address": "Beijing", + "email": "xxx@xxx.com", + "level.a.b": "deep level", }, "sex": "man", "user_list": [][]map[string]any{ @@ -170,14 +169,17 @@ func TestExpandArrayPath(t *testing.T) { PathList: nil, PathMap: nil, } + ExpandArrayPath(jsonStr, "company_info.{{#level.a.b#}}", "company_info.a-b", pathExpendRes) + ExpandArrayPath(jsonStr, "person_list.{{idx}}.{{#a.b#}}", "person_list.{{idx}}.a-b", pathExpendRes) ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.age", "a.{{idx}}.{{idx}}.b", pathExpendRes) ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.name", "e.{{idx}}.{{idx}}.c", pathExpendRes) ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.sex", "f.{{idx}}.{{idx}}.c", pathExpendRes) - res := "" + // res := "" for _, item := range pathExpendRes.PathList { - res, _ = sjson.Set(res, pathExpendRes.PathMap[item], gjson.Get(jsonStr, item).Value()) + // fmt.Println(item, pathExpendRes.PathMap[item]) + fmt.Println(item, pathExpendRes.PathMap[item], Get(gjson.Parse(jsonStr), item).String()) + // res, _ = sjson.Set(res, pathExpendRes.PathMap[item], Get(gjson.Parse(jsonStr), item).Value()) } - fmt.Println(res) } func TestGet(t *testing.T) {