构建JSON数据结构同时, 返回字段类型以及示例值

This commit is contained in:
白茶清欢 2022-01-10 23:26:50 +08:00
parent 186f103fa5
commit e41868db08
2 changed files with 205 additions and 3 deletions

View File

@ -125,3 +125,45 @@ func TestParse(t *testing.T) {
byteData, _ := json.Marshal(source) byteData, _ := json.Marshal(source)
fmt.Println(GetJSONDataStruct(string(byteData))) fmt.Println(GetJSONDataStruct(string(byteData)))
} }
// TestParseWithType 测试获取JSON数据结构
//
// Author : go_developer@163.com<张德满>
//
// Date : 10:59 PM 2022/1/9
func TestParseWithType(t *testing.T) {
source := map[string]interface{}{
"name": "zhangdeman",
"extra": map[string]interface{}{
"age": 18,
"height": 180,
"slice": []int{1, 2, 3},
"obj": map[string]interface{}{
"la": "aaaa",
},
},
"slice": []int{1, 2, 3},
"map": map[string]interface{}{"a": 1, "d": 5.5, "e": "qqq"},
"empty_obj": map[string]interface{}{},
"empty_list": make([]interface{}, 0),
"table": []map[string]interface{}{
{"name": "alex", "age": 18, "number": 1, "obj": map[string]interface{}{"enen": "en"}},
{"name": "bob", "age": 28, "number": 2},
},
"two_slice": []map[string]interface{}{
{
"students": []map[string]interface{}{
{
"name": "enen",
"age": 18,
"score": []float64{1, 2, 3, 45},
},
},
"other": []interface{}{"others"},
"read_only": 1,
},
},
}
byteData, _ := json.Marshal(source)
fmt.Println(GetJSONDataStructWithType(string(byteData)))
}

View File

@ -8,10 +8,52 @@
package json_tool package json_tool
import ( import (
"strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tidwall/gjson" "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数据的结构 // GetJSONDataStruct 获取JSON数据的结构
// //
// Author : go_developer@163.com<张德满> // Author : go_developer@163.com<张德满>
@ -24,12 +66,20 @@ func GetJSONDataStruct(data string) ([]string, error) {
pathList := make([]string, 0) pathList := make([]string, 0)
r := gjson.Parse(data) r := gjson.Parse(data)
r.ForEach(func(key, value gjson.Result) bool { r.ForEach(func(key, value gjson.Result) bool {
if value.Value() == nil {
pathList = append(pathList, key.String())
return true
}
if value.IsObject() { if value.IsObject() {
if value.String() == "{}" {
pathList = append(pathList, key.String())
} else {
list, _ := GetJSONDataStruct(value.String()) list, _ := GetJSONDataStruct(value.String())
for _, k := range list { for _, k := range list {
pathList = append(pathList, key.String()+"."+k) pathList = append(pathList, key.String()+"."+k)
} }
} }
}
if value.IsArray() { if value.IsArray() {
dataList := value.Array() dataList := value.Array()
@ -55,3 +105,113 @@ func GetJSONDataStruct(data string) ([]string, error) {
}) })
return pathList, nil 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
}
}