diff --git a/filter.go b/filter.go index 1558979..8ca7dfe 100644 --- a/filter.go +++ b/filter.go @@ -10,14 +10,13 @@ package filter import ( "encoding/json" "fmt" + "git.zhangdeman.cn/zhangdeman/wrapper" "strings" "github.com/tidwall/gjson" "github.com/tidwall/sjson" "errors" - - "git.zhangdeman.cn/zhangdeman/util" ) // NewFilter 过滤器实例 @@ -64,17 +63,7 @@ func (f *filter) Deal() error { continue } sourceResult := gjson.Get(f.sourceData, rule.SourcePath) - var ( - sourceVal string - ) - - if !sourceResult.Exists() { - // 不存在, 使用默认值 - sourceVal = rule.DefaultValue - } else { - sourceVal = sourceResult.String() - } - if formatVal, err = f.getValue(rule.DataType, sourceVal); nil != err { + if formatVal, err = f.getValue(rule.DataType, sourceResult, rule.DefaultValue); nil != err { return fmt.Errorf("%s = %v can not convert to %s : %s", rule.SourcePath, sourceResult.Value(), rule.DataType, err.Error()) } if f.formatResult, err = sjson.Set(f.formatResult, rule.MapPath, formatVal); nil != err { @@ -183,56 +172,60 @@ func (f *filter) Parse(receiver interface{}) error { // Author : go_developer@163.com<白茶清欢> // // Date : 12:25 2022/7/4 -func (f *filter) getValue(dataType string, defaultValue string) (interface{}, error) { +func (f *filter) getValue(dataType string, sourceValue gjson.Result, defaultValue string) (interface{}, error) { + sourceValueStr := defaultValue + if sourceValue.Exists() { + str := sourceValue.String() + if len(str) > 0 { + sourceValueStr = str + } + } + + strVal := wrapper.String(sourceValueStr) + switch dataType { - case "int8": + case wrapper.DataTypeInt8: + return strVal.ToInt8() + case wrapper.DataTypeInt16: + return strVal.ToInt16() + case wrapper.DataTypeInt32: + return strVal.ToInt32() + case wrapper.DataTypeInt64: + return strVal.ToInt64() + case wrapper.DataTypeInt: + return strVal.ToInt() + case wrapper.DataTypeUint8: + return strVal.ToUint8() + case wrapper.DataTypeUint16: + return strVal.ToUint16() + case wrapper.DataTypeUint32: + return strVal.ToUint32() + case wrapper.DataTypeUint64: + return strVal.ToUint64() + case wrapper.DataTypeUint: + return strVal.ToUint() + case wrapper.DataTypeBool: + return strVal.ToBool() + case wrapper.DataTypeFloat32: + return strVal.ToFloat64() + case wrapper.DataTypeFloat64: fallthrough - case "int16": + case wrapper.DataTypeFloat: fallthrough - case "int32": - fallthrough - case "int64": - fallthrough - case "int": - var ( - err error - val int64 - ) - err = util.ConvertAssign(&val, defaultValue) - return val, err - case "uint8": - fallthrough - case "uint16": - fallthrough - case "uint32": - fallthrough - case "uint64": - fallthrough - case "uint": - var ( - err error - val uint64 - ) - err = util.ConvertAssign(&val, defaultValue) - return val, err - case "bool": - var ( - err error - val bool - ) - err = util.ConvertAssign(&val, defaultValue) - return val, err - case "float32": - fallthrough - case "float64": - var ( - err error - val float64 - ) - err = util.ConvertAssign(&val, defaultValue) - return val, err - case "string": - return defaultValue, nil + case wrapper.DataTypeDouble: + return strVal.ToFloat64() + case wrapper.DataTypeNumber: + return strVal.ToNumber() + case wrapper.DataTypeString: + return sourceValueStr, nil + case wrapper.DataTypeAny: + return sourceValue.Value(), nil + case wrapper.DataTypeAnySlice: + // 任意类型的list + return strVal.ToAnySlice() + case wrapper.DataTypeObject: + // object + return strVal.ToObject() default: return nil, errors.New(dataType + " is not support!") } diff --git a/go.mod b/go.mod index af271f9..b81a9f6 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,10 @@ module git.zhangdeman.cn/zhangdeman/json_filter -go 1.17 +go 1.18 require ( git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20220627070212-c590a0a1c216 - git.zhangdeman.cn/zhangdeman/util v0.0.0-20230211164227-256094968151 + git.zhangdeman.cn/zhangdeman/util v0.0.0-20230505025924-96532aff0019 github.com/Jeffail/gabs v1.4.0 github.com/pkg/errors v0.9.1 github.com/smartystreets/goconvey v1.7.2 @@ -13,12 +13,15 @@ require ( ) require ( + git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505080742-fa2f27724d76 // indirect github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mssola/user_agent v0.6.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/smartystreets/assertions v1.2.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect diff --git a/go.sum b/go.sum index b28f983..dfa91ed 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,18 @@ git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20220627070212-c590a0a1c216/go.mod git.zhangdeman.cn/zhangdeman/util v0.0.0-20220626081130-cbac0b676fb8/go.mod h1:G2/OKMbEn89d+YUXQtv9Nlh0LGg14pOqDnbOgBTTRXY= git.zhangdeman.cn/zhangdeman/util v0.0.0-20230211164227-256094968151 h1:j537bRLQL1FlkdXTIaT9Ecjx5eogkPsGiTOWIEFQlc8= git.zhangdeman.cn/zhangdeman/util v0.0.0-20230211164227-256094968151/go.mod h1:SyRTkOz6gxUVn3S/Qtkf+rhKV0I1ym8lwsT8YjggYFs= +git.zhangdeman.cn/zhangdeman/util v0.0.0-20230330065032-faba0a5a9ea1 h1:u2FdNfcGvRmlKpuPBk2qvYenkZjinHY2PLu5Wmhka8A= +git.zhangdeman.cn/zhangdeman/util v0.0.0-20230330065032-faba0a5a9ea1/go.mod h1:SyRTkOz6gxUVn3S/Qtkf+rhKV0I1ym8lwsT8YjggYFs= +git.zhangdeman.cn/zhangdeman/util v0.0.0-20230330082619-662152cb682d h1:kMQZmkYBceHM3O7wiCelSADjTyOF3EBxXTX8fgZA+6c= +git.zhangdeman.cn/zhangdeman/util v0.0.0-20230330082619-662152cb682d/go.mod h1:qeVsrMae8ljqzcsmI+lWPU/4Rdjb9cOt4oaDUNEf1Ck= +git.zhangdeman.cn/zhangdeman/util v0.0.0-20230505025924-96532aff0019 h1:eJ/9rEj2iI8P9I1DfCmMUvsV+n2EiAWCXnI9yVVDHO0= +git.zhangdeman.cn/zhangdeman/util v0.0.0-20230505025924-96532aff0019/go.mod h1:z2bP5LIwRVpWSQV0/a3WIFaoarJUP8kA/0Clv0bP+8I= +git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505064614-5e785171ed67 h1:DH9K3fNddpFxRGLkcLP5MHsAQVinpWpmGzbVBf8yrKM= +git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505064614-5e785171ed67/go.mod h1:2jc48WuVoHxZjkvlBewzp+ey8khP1K4OOcibVD1yL2k= +git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505070245-b182b21e039b h1:ZwAA10/+v3FFAq5/EzjXdXDodmKppXb5gBkCcgaYVBo= +git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505070245-b182b21e039b/go.mod h1:2jc48WuVoHxZjkvlBewzp+ey8khP1K4OOcibVD1yL2k= +git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505080742-fa2f27724d76 h1:IEixZNZY3/nqb5v9PzzgSeXLPp0U7wRaxrM+ZaSh+j0= +git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505080742-fa2f27724d76/go.mod h1:2jc48WuVoHxZjkvlBewzp+ey8khP1K4OOcibVD1yL2k= github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo= github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ= @@ -18,6 +30,10 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mssola/user_agent v0.6.0 h1:uwPR4rtWlCHRFyyP9u2KOV0u8iQXmS7Z7feTrstQwk4= +github.com/mssola/user_agent v0.6.0/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/tree/REDME.md b/tree/REDME.md new file mode 100644 index 0000000..e74d0a8 --- /dev/null +++ b/tree/REDME.md @@ -0,0 +1,3 @@ +# 说明 + +基于JSON数据生成数据树 diff --git a/tree/consts.go b/tree/consts.go new file mode 100644 index 0000000..2085e53 --- /dev/null +++ b/tree/consts.go @@ -0,0 +1,73 @@ +// Package tree ... +// +// Description : tree ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2023-03-28 18:32 +package tree + +const ( + // KeywordObjectStart 对象开始标识 + KeywordObjectStart = "{" + // KeywordObjectEnd 对象结束标识 + KeywordObjectEnd = "}" + // KeywordArrayStart 数组开始标识 + KeywordArrayStart = "[" + // KeywordArrayEnd 数组结束标识 + KeywordArrayEnd = "]" + // KeywordColon 冒号 + KeywordColon = ":" + // KeywordComma 逗号 + KeywordComma = "," + // KeywordDot . + KeywordDot = "." + // KeywordDoubleQuote 双引号 + KeywordDoubleQuote = `"` + // KeywordEscapeSymbol 转义符号 + KeywordEscapeSymbol = `\` + // KeywordSpace 空格 + KeywordSpace = " " + // KeywordMinus 负号 + KeywordMinus = "-" + // KeywordTrueStart true的起始值 + KeywordTrueStart = "t" + // KeywordFalseStart false的起始值 + KeywordFalseStart = "f" + KeywordZero = "0" + KeywordOne = "1" + KeywordTwo = "2" + KeywordThree = "3" + KeywordFour = "4" + KeywordFive = "5" + KeywordSix = "6" + KeywordSeven = "7" + KeywordEight = "8" + KeywordNine = "9" +) + +const ( + // ValueTypeString 字符串类型 + ValueTypeString = "string" + // ValueTypeBool bool类型 + ValueTypeBool = "bool" + // ValueTypeInteger int类型 + ValueTypeInteger = "int64" + // ValueTypeFloat float类型 + ValueTypeFloat = "float64" + // ValueTypeNumber 数字 + ValueTypeNumber = "number" + // ValueTypeMap map数据 + ValueTypeMap = "map" + // ValueTypeArray 数组 + ValueTypeArray = "array" +) + +// isBaseDataType 是否为基础数据类型 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 23:16 2023/3/28 +func isBaseDataType(valueType string) bool { + return valueType != ValueTypeArray && valueType != ValueTypeMap +} diff --git a/tree/generate.go b/tree/generate.go new file mode 100644 index 0000000..0aa7d02 --- /dev/null +++ b/tree/generate.go @@ -0,0 +1,321 @@ +// Package tree ... +// +// Description : tree ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2023-03-28 18:42 +package tree + +import ( + "fmt" + "git.zhangdeman.cn/zhangdeman/util" + "strings" + + "github.com/pkg/errors" +) + +// New 生成一棵JSON树 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:42 2023/3/28 +func New(jsonData string) (*Generate, error) { + jsonData = strings.TrimSpace(jsonData) + g := &Generate{ + jsonData: jsonData, + jsonDataByte: []byte(jsonData), + } + g.root = NewVirtualNode() + g.currentNode = g.root + g.currentParentNode = g.root + err := g.init() + return g, err +} + +// Generate ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 22:46 2023/3/28 +type Generate struct { + root *Node // 根节点 + currentNode *Node // 当前节点 + currentParentNode *Node // 当前节点的父节点 + jsonData string + jsonDataByte []byte +} + +// init 初始化 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 21:23 2023/3/29 +func (g *Generate) init() error { + startIndex := 0 + var ( + jsonKey string + err error + valueType string + jsonValue string + ) + + // 获取类型 + if valueType, startIndex, err = g.getValueType(startIndex); nil != err { + return err + } + + g.root.ValueType = valueType + g.currentNode.ValueType = valueType + + for { + if startIndex >= len(g.jsonDataByte) { + break + } + + // 获取字段 + if jsonKey, startIndex, err = g.getKey(startIndex); nil != err { + return err + } + // 获取类型 + if valueType, startIndex, err = g.getValueType(startIndex); nil != err { + return err + } + // 获取值 + if jsonValue, startIndex, err = g.getValue(startIndex); nil != err { + return err + } + fmt.Println(jsonKey, valueType, jsonValue, startIndex) + // 创建节点, 并挂在到树上 + var newNode *Node + if util.Array.In(g.currentNode.ValueType, []string{ValueTypeArray, ValueTypeMap}) >= 0 { + newNode = NewNode(jsonKey, jsonValue, valueType, g.currentNode) + g.currentParentNode = g.currentNode + g.currentParentNode.SonNodeList = append(g.currentParentNode.SonNodeList, newNode) + } else { + newNode = NewNode(jsonKey, jsonValue, valueType, g.currentParentNode) + } + g.currentNode = newNode + } + return nil +} + +// getKey 获取jsonKey TODO : 转义符识别 +// +// Author : zhangdeman001@ke.com<张德满> +// +// Date : 11:36 2023/3/29 +func (g *Generate) getKey(startIndex int) (string, int, error) { + keyCharList := make([]string, 0) + hasStart := false + for startIndex < len(g.jsonDataByte) { + charStr := string(g.jsonDataByte[startIndex]) + if charStr == KeywordSpace && !hasStart { + // 跳过空格 + startIndex++ + continue + } + + if charStr == KeywordDoubleQuote && !hasStart { + // 第一次遇见双引号 + startIndex++ + hasStart = true + continue + } + if charStr == KeywordDoubleQuote && hasStart { + // 第二次遇见双引号,key探寻结束 + startIndex++ + break + } + + if !hasStart { + if util.Array.In(charStr, []string{ + KeywordDoubleQuote, + KeywordObjectStart, + KeywordArrayStart, + KeywordComma, + }) >= 0 { + startIndex++ + continue + } + return "", startIndex, errors.New("parse key : format is invalid") + } + + if charStr == KeywordEscapeSymbol { + // 转义符 + startIndex++ + if startIndex >= len(g.jsonDataByte) { + // 转义符后面没东西了 + return "", startIndex, errors.New("escape symbol without any data") + } + charStr = string(g.jsonDataByte[startIndex]) + } + keyCharList = append(keyCharList, charStr) + startIndex++ + } + jsonKey := strings.Join(keyCharList, "") + + return jsonKey, startIndex, nil +} + +// getValueType 获取数据类型 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 14:37 2023/3/29 +func (g *Generate) getValueType(startIndex int) (string, int, error) { + if startIndex == 0 { + // 初始对象特殊处理 + if string(g.jsonDataByte[0]) == KeywordArrayStart { + return ValueTypeArray, 1, nil + } + + // 初始对象特殊处理 + if string(g.jsonDataByte[0]) == KeywordObjectStart { + return ValueTypeMap, 1, nil + } + + return "", 0, errors.New("root data parse : value is invalid") + } + // 指针向后, 探寻到冒号之后第一个非空格字符串 + hasFindColon := false + for startIndex < len(g.jsonDataByte) { + charStr := string(g.jsonDataByte[startIndex]) + if !hasFindColon { + if charStr == KeywordSpace { + // 跳过空格 + startIndex++ + continue + } + if charStr != KeywordSpace { + // 非空格 + if charStr != KeywordColon { + return "", startIndex, errors.New("value is invalid") + } + startIndex++ + hasFindColon = true + break + } + } + } + + if !hasFindColon { + return "", startIndex, errors.New("check json value type : value is invalid") + } + + keyValType := "" + // 冒号后面探寻值的类型 + for startIndex < len(g.jsonDataByte) { + charStr := string(g.jsonDataByte[startIndex]) + if charStr == KeywordSpace { + // 跳过空格 + startIndex++ + continue + } + + // 非空 + switch charStr { + case KeywordMinus: + fallthrough + case KeywordOne: + fallthrough + case KeywordTwo: + fallthrough + case KeywordThree: + fallthrough + case KeywordFour: + fallthrough + case KeywordFive: + fallthrough + case KeywordSix: + fallthrough + case KeywordSeven: + fallthrough + case KeywordEight: + fallthrough + case KeywordNine: + keyValType = ValueTypeNumber + case KeywordDoubleQuote: + keyValType = ValueTypeString + case KeywordArrayStart: + keyValType = ValueTypeArray + case KeywordObjectStart: + keyValType = ValueTypeMap + default: + return "", startIndex, errors.New("validate json value type : value type is invalid") + } + break + } + return keyValType, startIndex, nil +} + +// getValue 获取JSON值 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:09 2023/3/30 +func (g *Generate) getValue(startIndex int) (string, int, error) { + valArr := make([]string, 0) + isStart := false + for startIndex < len(g.jsonDataByte) { + str := string(g.jsonDataByte[startIndex]) + if str == KeywordSpace && !isStart { + startIndex++ + continue + } + if !isStart { + if util.Array.In(str, []string{KeywordArrayEnd, KeywordObjectEnd, KeywordComma}) >= 0 { + startIndex++ + continue + } + } + if isStart { + if util.Array.In(str, []string{KeywordDoubleQuote, KeywordArrayEnd, KeywordObjectEnd, KeywordComma}) >= 0 { + // 值的拼接已结束 + startIndex++ + break + } + } + if str == KeywordDoubleQuote { + if isStart { + startIndex++ + break + } else { + startIndex++ + isStart = true + continue + } + } + isStart = true + if str == KeywordEscapeSymbol { + // 转义符 + startIndex++ + if startIndex >= len(g.jsonDataByte) { + // 转义符后面没东西了 + return "", startIndex, errors.New("escape symbol without any data") + } + str = string(g.jsonDataByte[startIndex]) + } + valArr = append(valArr, str) + startIndex++ + } + return strings.Join(valArr, ""), startIndex, nil +} + +// isObject 整体是否为对象 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 22:51 2023/3/28 +func (g *Generate) isObject() bool { + return strings.HasPrefix(g.jsonData, KeywordObjectStart) +} + +// isArray 整体是否为数组 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 22:51 2023/3/28 +func (g *Generate) isArray() bool { + return strings.HasPrefix(g.jsonData, KeywordArrayStart) +} diff --git a/tree/generate_test.go b/tree/generate_test.go new file mode 100644 index 0000000..a124fa3 --- /dev/null +++ b/tree/generate_test.go @@ -0,0 +1,23 @@ +// Package tree ... +// +// Description : tree ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2023-03-29 21:32 +package tree + +import ( + "fmt" + "testing" +) + +func TestNew(t *testing.T) { + jsonData := `{"name": "zhang", "age":17}` + g, err := New(jsonData) + if nil != err { + fmt.Println(err.Error()) + return + } + fmt.Println(g) +} diff --git a/tree/node.go b/tree/node.go new file mode 100644 index 0000000..8b8885b --- /dev/null +++ b/tree/node.go @@ -0,0 +1,108 @@ +// Package tree ... +// +// Description : tree ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2023-03-28 18:12 +package tree + +import ( + "strings" + + "git.zhangdeman.cn/zhangdeman/util" +) + +// Node 节点的数据结构 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:12 2023/3/28 +type Node struct { + IsVirtual bool // 是否虚拟节点, 主要应对输入的原始数据为list这一场景 + Value interface{} // 节点的值 + ValueType string // 数据类型 string / int64 / float64 / map / list / nil + Key string // 节点的key名称(输入的原始名称) + Show bool // 节点是否可见 + ShowKey string // 重新序列化后, 对外输出的Key + AllowEdit bool // 当前key是否允许编辑 + AllowChangeType bool // 在允许编辑的情况下, 是否允许修改数据类型 + DefaultValue interface{} // 输入为value为nil时候的默认值 + ParentNode *Node // 父节点 + PreBrotherNode *Node // 前一个兄弟节点 + LastBrotherNode *Node // 下一个兄弟节点 + SonNodeList []*Node // 子节点列表 + ObjectStack []string // 对象信息堆栈, 利用栈的括号匹配, 判断某一个对象是否扫面完成 +} + +// NewNode 创建新节点 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 23:02 2023/3/28 +func NewNode(key string, value string, valueType string, parentNode *Node) *Node { + n := &Node{ + IsVirtual: false, + Value: value, + ValueType: valueType, + Key: key, + Show: false, + ShowKey: "", + AllowEdit: false, + AllowChangeType: false, + DefaultValue: nil, + ParentNode: parentNode, + PreBrotherNode: nil, + LastBrotherNode: nil, + SonNodeList: nil, + ObjectStack: make([]string, 0), + } + + switch valueType { + case ValueTypeString: + n.Value = value + case ValueTypeInteger: + var v int64 + _ = util.ConvertAssign(&v, value) + n.Value = v + case ValueTypeFloat: + var v float64 + _ = util.ConvertAssign(&v, value) + n.Value = v + case ValueTypeBool: + n.Value = strings.ToLower(value) == "true" + case ValueTypeMap: + n.Value = map[string]interface{}{} + n.SonNodeList = make([]*Node, 0) + case ValueTypeArray: + n.Value = []interface{}{} + n.SonNodeList = make([]*Node, 0) + } + + // 处理 preBrother 和 lastBrother + if parentNode.ValueType == ValueTypeMap || parentNode.ValueType == ValueTypeArray { + // map 和 array 才有所谓的兄弟节点 + if len(parentNode.SonNodeList) > 0 { + // 设置新节点的 pre 节点 + n.PreBrotherNode = parentNode.SonNodeList[len(parentNode.SonNodeList)-1] + // 设置当前最后一个节点的 last 节点 + parentNode.SonNodeList[len(parentNode.SonNodeList)-1].LastBrotherNode = n + } + // 新节点追加到子节点末尾 + parentNode.SonNodeList = append(parentNode.SonNodeList, n) + } + return n +} + +// NewVirtualNode 创建一个新的虚拟节点 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 23:08 2023/3/28 +func NewVirtualNode() *Node { + return &Node{ + IsVirtual: true, + SonNodeList: make([]*Node, 0), + ObjectStack: make([]string, 0), + } +}