// Package json_tool ... // // Description : json_tool ... // // Author : go_developer@163.com<张德满> // // Date : 2022-01-09 10:48 PM package json_tool import ( "strings" "github.com/pkg/errors" "github.com/tidwall/gjson" ) // Field ... // // Author : go_developer@163.com<张德满> // // Date : 2022/1/10 10:47 PM type Field struct { Path string `json:"path"` // 路径 Type string `json:"type"` // 类型 Example string `json:"example"` // 示例值 } const ( // FieldTypeInt ... FieldTypeInt = "int64" // FieldTypeIntSlice ... FieldTypeIntSlice = "[]int64" // FieldTypeFloat ... FieldTypeFloat = "float64" // FieldTypeFloatSlice ... FieldTypeFloatSlice = "[]float64" // FieldTypeBool ... FieldTypeBool = "bool" // FieldTypeBoolSlice ... FieldTypeBoolSlice = "[]bool" // FieldTypeString ... FieldTypeString = "string" // FieldTypeStringSLice ... FieldTypeStringSLice = "string" // FieldTypeAny ... FieldTypeAny = "interface{}" // FieldTypeAnySlice ... FieldTypeAnySlice = "[]interface{}" // FieldTypeSlice ... FieldTypeSlice = "[]interface{}" // FieldTypeMap ... FieldTypeMap = "map" // FieldTypeMapSlice ... FieldTypeMapSlice = "[]map" ) // GetJSONDataStruct 获取JSON数据的结构 // // Author : go_developer@163.com<张德满> // // Date : 10:53 PM 2022/1/9 func GetJSONDataStruct(data string) ([]string, error) { if !gjson.Valid(data) { return make([]string, 0), errors.New("JSON format is invalid") } pathList := make([]string, 0) r := gjson.Parse(data) r.ForEach(func(key, value gjson.Result) bool { if value.Value() == nil { pathList = append(pathList, key.String()) return true } if value.IsObject() { if value.String() == "{}" { pathList = append(pathList, key.String()) } else { list, _ := GetJSONDataStruct(value.String()) for _, k := range list { pathList = append(pathList, key.String()+"."+k) } } } if value.IsArray() { dataList := value.Array() if len(dataList) > 0 { if !dataList[0].IsObject() && !dataList[0].IsArray() { pathList = append(pathList, key.String()) } else { list, _ := GetJSONDataStruct(dataList[0].String()) for _, k := range list { pathList = append(pathList, key.String()+".[]."+k) } } } else { pathList = append(pathList, key.String()) } } if !value.IsObject() && !value.IsArray() { pathList = append(pathList, key.String()) } return true }) return pathList, nil } // GetJSONDataStructWithType 获取数据结构,并获取类型 // // Author : go_developer@163.com<张德满> // // Date : 2022/1/10 10:47 PM func GetJSONDataStructWithType(data string) ([]Field, error) { if !gjson.Valid(data) { return make([]Field, 0), errors.New("JSON format is invalid") } pathList := make([]Field, 0) r := gjson.Parse(data) r.ForEach(func(key, value gjson.Result) bool { if value.Value() == nil { pathList = append(pathList, Field{ Path: key.String(), Type: FieldTypeAny, Example: "nil", }) return true } if value.IsObject() { if value.String() == "{}" { pathList = append(pathList, Field{ Path: key.String(), Type: FieldTypeMap, Example: "{}", }) } else { list, _ := GetJSONDataStructWithType(value.String()) for _, field := range list { pathList = append(pathList, Field{ Path: key.String() + "." + field.Path, Type: field.Type, Example: field.Example, }) } } } if value.IsArray() { dataList := value.Array() if len(dataList) > 0 { if !dataList[0].IsObject() && !dataList[0].IsArray() { pathList = append(pathList, Field{ Path: key.String(), Type: "[]" + GetDataType(dataList[0]), Example: value.String(), }) } else { list, _ := GetJSONDataStructWithType(dataList[0].String()) for _, field := range list { pathList = append(pathList, Field{ Path: key.String() + ".[]." + field.Path, Type: field.Type, Example: field.Example, }) } } } else { pathList = append(pathList, Field{ Path: key.String(), Type: FieldTypeSlice, Example: "[]", }) } } if !value.IsObject() && !value.IsArray() { pathList = append(pathList, Field{ Path: key.String(), Type: GetDataType(value), Example: value.String(), }) } return true }) return pathList, nil } // GetDataType 获取数据类型 // // Author : go_developer@163.com<张德满> // // Date : 2022/1/10 11:00 PM func GetDataType(value gjson.Result) string { switch value.Type.String() { default: return FieldTypeAny case "Null": return FieldTypeAny case "False": return FieldTypeBool case "True": return FieldTypeBool case "Number": if strings.Contains(value.String(), ".") { return FieldTypeFloat } return FieldTypeInt case "String": return FieldTypeString case "JSON": if strings.HasPrefix(strings.TrimSpace(value.String()), "[") { return FieldTypeSlice } return FieldTypeMap } }