// Package wrapper ... // // Description : wrapper ... // // Author : go_developer@163.com<白茶清欢> // // Date : 2025-04-28 15:32 package wrapper import ( "encoding/xml" "errors" "fmt" dynamicstruct "git.zhangdeman.cn/zhangdeman/dynamic-struct" "git.zhangdeman.cn/zhangdeman/serialize" "github.com/tidwall/gjson" ) func NewJson(sourceData string, o *Option) (*ownJson, error) { gjsonRes := gjson.Parse(sourceData) if gjsonRes.Value() == nil { return nil, errors.New("source data parse result is nil") } // 仅支持map if !gjsonRes.IsObject() { return nil, errors.New("source result is not map or struct Marshal string") } if nil == o { o = &Option{} } if o.XmlName == "" { o.XmlName = "XmlData" } oj := &ownJson{ sourceData: sourceData, gjsonResult: gjsonRes, structBuilder: dynamicstruct.NewStruct(nil), o: o, } if err := oj.GenerateStruct(); nil != err { return nil, err } return oj, nil } type ownJson struct { sourceData string // 数据源 gjsonResult gjson.Result // 数据源解析为gjson structBuilder dynamicstruct.IBuilder // 结构体构造器 structRes any // 解析的结构体值 o *Option // 一些操作选项 } // GenerateStruct 生成结构体字段列表 func (oj *ownJson) GenerateStruct() error { oj.gjsonResult.ForEach(func(fieldName, fieldValue gjson.Result) bool { oj.generateStructField("", fieldName.String(), fieldValue) return true }) // 追加xml的标签 oj.structBuilder.AddField("XMLName", "", xml.Name{}, fmt.Sprintf(`json:"-" toml:"-" yml:"-" init:"-" xml:"%v"`, oj.o.XmlName), false) val := oj.structBuilder.Build().New() if err := serialize.JSON.UnmarshalWithNumber([]byte(oj.sourceData), &val); nil != err { return err } oj.structRes = val return nil } // Marshal 结果序列化 func (oj *ownJson) Marshal(marshalType string) ([]byte, error) { return serialize.Wrapper.Marshal(marshalType, oj.structRes) } // generateStructField 递归解析 func (oj *ownJson) generateStructField(rootPath string, currentName string, currentResult gjson.Result) { structPath := oj.getPath(rootPath, currentName) if currentResult.IsBool() { // bool类型 oj.structBuilder.AddField(structPath, "", true, "", false) return } if currentResult.Type == gjson.Number { // 数字类型, 统一用float64 oj.structBuilder.AddField(structPath, "", float64(0), "", false) return } if currentResult.Value() == nil { // 空值, any类型 oj.structBuilder.AddField(structPath, "", (*any)(nil), "", false) return } if currentResult.Type == gjson.String { // 字符串类型 oj.structBuilder.AddField(structPath, "", "", "", false) return } if currentResult.IsObject() { // 还是一个嵌套对象, 递归处理 currentResult.ForEach(func(key, value gjson.Result) bool { oj.generateStructField(structPath, key.String(), value) return true }) return } if currentResult.IsArray() { // 数组, 递归处理 arrList := currentResult.Array() if arrList[0].Type == gjson.True || arrList[0].Type == gjson.False { oj.structBuilder.AddField(structPath, "", []bool{}, "", false) return } if arrList[0].Type == gjson.Number { oj.structBuilder.AddField(structPath, "", []float64{}, "", false) return } if arrList[0].Type == gjson.String { oj.structBuilder.AddField(structPath, "", []string{}, "", false) return } if arrList[0].Type == gjson.Null { oj.structBuilder.AddField(structPath, "", []any{}, "", false) return } if arrList[0].IsArray() { // 数组就不递归处理了, 支持到二维 oj.structBuilder.AddField(structPath, "", [][]any{}, "", false) return } // 对象结构,递归处理 arrList[0].ForEach(func(key, value gjson.Result) bool { oj.generateStructField(structPath+".[]", key.String(), value) return true }) return } } // getPath 获取路径 func (oj *ownJson) getPath(root string, currentName string) string { if root == "" { return currentName } return root + "." + currentName }