diff --git a/json/build.go b/json/build.go index e85aafb..c888656 100644 --- a/json/build.go +++ b/json/build.go @@ -8,6 +8,7 @@ package json import ( + "fmt" "strings" "github.com/go-developer/gopkg/easylock" @@ -25,10 +26,11 @@ const ( // // Date : 10:33 下午 2021/3/10 type JSONode struct { - Key string // json key - Value interface{} // 对应的值 - Child []*JSONode // 子节点 - IsRoot bool // 是否根节点 + Key string // json key + Value interface{} // 对应的值 + Child []*JSONode // 子节点 + IsRoot bool // 是否根节点 + IsHasLastBrother bool // 在此之后是否有其他兄弟节点 } // NewDynamicJSON 获取JSON实例 @@ -72,6 +74,7 @@ func (dj *DynamicJSON) SetValue(path string, value interface{}) { for keyIndex, key := range pathList { searchRoot = dj.search(searchRoot, key) if nil != searchRoot { + searchRoot.Value = value // 查询到结果,更新值 parent = searchRoot } else { var val interface{} @@ -79,12 +82,66 @@ func (dj *DynamicJSON) SetValue(path string, value interface{}) { val = value } _ = dj.createNode(parent, key, val) - searchRoot = parent.Child[0] - parent = parent.Child[0] + searchRoot = parent.Child[len(parent.Child)-1] + parent = parent.Child[len(parent.Child)-1] } } } +// String 获取字符串的格式JSON +// +// Author : go_developer@163.com<张德满> +// +// Date : 2:16 下午 2021/3/11 +func (dj *DynamicJSON) String() string { + tplList := make([]string, 0) + valList := make([]interface{}, 0) + tplListResult, valListResult := dj.buildTpl(dj.root, &tplList, &valList) + return fmt.Sprintf(strings.Join(*tplListResult, ""), *valListResult...) +} + +// buildTpl 构建json模版与绑定数据 +// +// Author : go_developer@163.com<张德满> +// +// Date : 4:38 下午 2021/3/11 +func (dj *DynamicJSON) buildTpl(root *JSONode, tplList *[]string, valList *[]interface{}) (*[]string, *[]interface{}) { + if nil == root { + *tplList = append(*tplList, "}") + return tplList, valList + } + key := "\"" + root.Key + "\"" + if len(root.Child) > 0 { + if root.IsRoot { + *tplList = append(*tplList, "{") + } else { + *tplList = append(*tplList, key+":{") + } + } else { + if root.IsHasLastBrother { + *tplList = append(*tplList, key+":%v,") + } else { + *tplList = append(*tplList, key+":%v") + } + switch val := root.Value.(type) { + case string: + *valList = append(*valList, "\""+val+"\"") + default: + *valList = append(*valList, root.Value) + } + return tplList, valList + } + for _, node := range root.Child { + dj.buildTpl(node, tplList, valList) + } + if root.IsHasLastBrother { + *tplList = append(*tplList, "},") + } else { + *tplList = append(*tplList, "}") + } + return tplList, valList +} + // Search 搜索一个key TODO : 优化 // // Author : go_developer@163.com<张德满> @@ -118,11 +175,16 @@ func (dj *DynamicJSON) createNode(parent *JSONode, key string, value interface{} if parent.Child == nil { parent.Child = make([]*JSONode, 0) } + if len(parent.Child) > 0 { + // 存在子节点,设置当前子节点还有其他兄弟节点 + parent.Child[len(parent.Child)-1].IsHasLastBrother = true + } parent.Child = append(parent.Child, &JSONode{ - Key: key, - Value: value, - Child: make([]*JSONode, 0), - IsRoot: false, + Key: key, + Value: value, + Child: make([]*JSONode, 0), + IsRoot: false, + IsHasLastBrother: false, }) dj.nodeCnt++ _ = dj.lock.Unlock("") diff --git a/json/json_test.go b/json/json_test.go index b7b6f88..da4960b 100644 --- a/json/json_test.go +++ b/json/json_test.go @@ -15,6 +15,12 @@ import ( func TestJSON(t *testing.T) { tree := NewDynamicJSON() tree.SetValue("extra.height.value", 180) - tree.SetValue("extra.height.unit", "cm") - fmt.Println(tree.root) + tree.SetValue("extra.height.unit.use", "cm") + tree.SetValue("extra.height.unit.open", "1") + tree.SetValue("name", "zhangdeman") + tree.SetValue("good.name", "good") + tree.SetValue("work", "111") + tree.SetValue("good.price", "180") + tree.SetValue("good.unit", "$") + fmt.Println(tree.String()) }