From 48639ba59a05cc1fbf6ed4fcff9e89935a7eecb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 4 Dec 2024 20:50:13 +0800 Subject: [PATCH] =?UTF-8?q?gjson=E8=AF=BB=E5=8F=96=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E6=94=AF=E6=8C=81key=E5=90=8D=E7=A7=B0=E4=B8=AD=E5=8C=85?= =?UTF-8?q?=E5=90=AB.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gjson_hack/define.go | 5 +++ gjson_hack/path.go | 79 +++++++++++++++++++++++++++++++++++++++++ gjson_hack/path_test.go | 17 +++++++++ 3 files changed, 101 insertions(+) diff --git a/gjson_hack/define.go b/gjson_hack/define.go index 577d477..bf9fb3c 100644 --- a/gjson_hack/define.go +++ b/gjson_hack/define.go @@ -43,3 +43,8 @@ type ExpendArrayResult struct { PathList []string `json:"path_list"` // 路径列表 PathMap map[string]string `json:"path_map"` // 数据源路径 => 目标路径的处理 } + +const ( + SpecialKeyStart = "{{#" + SpecialKeyEnd = "#}}" +) diff --git a/gjson_hack/path.go b/gjson_hack/path.go index 1814ab8..10ef86c 100644 --- a/gjson_hack/path.go +++ b/gjson_hack/path.go @@ -242,3 +242,82 @@ func Result(gjsonResult gjson.Result) gjson.Result { } return Object(gjsonResult) } + +// Get 主要解决 key 中包含 . 的问题 +// +// 如 : {"person.name": "test"} 如何将 person.name 整体作为一个字段而非两个层级 +// +// 解决方案 : +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 20:17 2024/12/4 +func Get(gjsonResult gjson.Result, path string) gjson.Result { + if len(path) == 0 { + return gjsonResult + } + if !gjsonResult.Exists() { + return gjsonResult + } + if !gjsonResult.IsObject() && !gjsonResult.IsArray() { + return gjsonResult + } + if !IsSpecialPath(path) { + // 不是特殊路径 + return gjsonResult + } + pathArr := strings.Split(path, ".") + normalPathList := make([]string, 0) + specialKeyList := make([]string, 0) + specialKeyHasStart := false + for idx, item := range pathArr { + if strings.HasPrefix(item, SpecialKeyStart) { + specialKeyHasStart = true + specialKeyList = append(specialKeyList, item) + continue + } + if strings.HasSuffix(item, SpecialKeyEnd) { + specialKeyHasStart = false + specialKeyList = append(specialKeyList, item) + sourceResult := gjsonResult + if len(normalPathList) > 0 { + sourceResult = gjsonResult.Get(strings.Join(normalPathList, ".")) + } + realKeyName := GetRealKeyName(strings.Join(specialKeyList, ".")) + return Get(sourceResult.Map()[realKeyName], strings.Join(pathArr[idx+1:], ".")) + } + if specialKeyHasStart { + specialKeyList = append(specialKeyList, item) + continue + } + normalPathList = append(normalPathList, item) + } + return gjsonResult +} + +// IsSpecialPath 判断传入的是否为特殊路径 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 20:27 2024/12/4 +func IsSpecialPath(path string) bool { + return strings.Contains(path, SpecialKeyStart) && strings.Contains(path, SpecialKeyEnd) +} + +// IsSpecialKey 判断是否特殊key +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 20:29 2024/12/4 +func IsSpecialKey(key string) bool { + return strings.HasPrefix(key, SpecialKeyStart) && strings.HasSuffix(key, SpecialKeyEnd) +} + +// GetRealKeyName ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 20:31 2024/12/4 +func GetRealKeyName(key string) string { + return strings.TrimSuffix(strings.TrimPrefix(key, SpecialKeyStart), SpecialKeyEnd) +} diff --git a/gjson_hack/path_test.go b/gjson_hack/path_test.go index 1848b11..0d22ce4 100644 --- a/gjson_hack/path_test.go +++ b/gjson_hack/path_test.go @@ -179,3 +179,20 @@ func TestExpandArrayPath(t *testing.T) { } fmt.Println(res) } + +func TestGet(t *testing.T) { + mapData := map[string]any{ + "person.name": "test", + "test": map[string]any{ + "a.b": "c", + "d.e": map[string]any{ + "e.f": "g", + }, + }, + } + byteData, _ := json.Marshal(mapData) + gjsonResult := gjson.ParseBytes(byteData) + fmt.Println(Get(gjsonResult, "{{#person.name#}}").String()) + fmt.Println(Get(gjsonResult, "test.{{#a.b#}}").String()) + fmt.Println(Get(gjsonResult, "test.{{#d.e#}}.{{#e.f#}}").String()) +}