gopkg/json_tool/filter.go

133 lines
3.1 KiB
Go
Raw Normal View History

2021-09-09 14:31:40 +08:00
// Package json_tool ...
//
// Description : 将复杂数据结构转化为 JSONNode 树
//
2021-07-25 19:05:59 +08:00
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-03-14 10:40 下午
2021-09-09 14:31:40 +08:00
package json_tool
import (
"encoding/json"
"fmt"
"reflect"
2021-04-13 21:53:36 +08:00
"strings"
"github.com/tidwall/gjson"
"github.com/pkg/errors"
2021-07-25 18:50:56 +08:00
"git.zhangdeman.cn/zhangdeman/gopkg/util"
)
// NewParseJSONTree 获取解析的实例
//
2021-07-25 19:05:59 +08:00
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:43 下午 2021/3/14
2021-09-10 11:36:48 +08:00
func NewFilter(data interface{}, rule map[string]string) *Filter {
return &Filter{
data: data,
rule: rule,
}
}
// ParseJSONTree 解析json树
//
2021-07-25 19:05:59 +08:00
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:41 下午 2021/3/14
2021-09-10 11:36:48 +08:00
type Filter struct {
data interface{}
2021-09-10 11:36:48 +08:00
rule map[string]string
}
2021-09-10 11:36:48 +08:00
// Result 数据过滤结果
//
2021-07-25 19:05:59 +08:00
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:44 下午 2021/3/14
2021-09-10 11:36:48 +08:00
func (f *Filter) Result() (*DynamicJSON, error) {
if !f.isLegalData() {
2021-04-13 21:53:36 +08:00
return nil, errors.New("非法的数据,无法转换成json")
}
result := NewDynamicJSON()
2021-09-10 11:36:48 +08:00
byteData, _ := json.Marshal(f.data)
2021-04-13 21:53:36 +08:00
source := string(byteData)
2021-09-10 11:36:48 +08:00
for extraDataPath, newDataPath := range f.rule {
2021-04-13 21:53:36 +08:00
// 为数组的处理
2021-09-10 11:36:48 +08:00
pathArr := strings.Split(extraDataPath, ".[].")
val := gjson.Get(source, pathArr[0])
if len(pathArr) == 1 {
2021-09-10 18:05:49 +08:00
f.SetValue(result, newDataPath, val.Value(), false, 0)
continue
}
// 支持list再抽取一层,处于性能考虑,这么限制,不做递归无限深度处理
// 还能继续抽取,就认为是 []map[string]interface{}
2021-09-10 11:36:48 +08:00
ketList := strings.Split(pathArr[1], ".")
for idx, item := range val.Array() {
data := item.Map()
for _, key := range ketList {
if v, exist := data[key]; exist {
2021-09-10 11:45:47 +08:00
result.SetValue(strings.ReplaceAll(newDataPath, "[]", fmt.Sprintf("[%d]", idx)), data[key].Raw, v.IsObject() || v.IsArray())
}
// 结果集中不存在对应key,丢弃
2021-04-13 21:53:36 +08:00
}
}
}
return result, nil
}
2021-09-10 18:05:49 +08:00
// SetValue 设置值
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 12:14 下午 2021/9/10
func (f *Filter) SetValue(result *DynamicJSON, path string, val interface{}, isSetSlice bool, sliceIndex int) {
if !isSetSlice {
result.SetValue(path, val, false)
return
}
}
// isLegalData 判断是否能转换成json结构, 只有slice/map/struct/能转换成slice或map的[]byte是合法的
//
2021-07-25 19:05:59 +08:00
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:46 下午 2021/3/14
2021-09-10 11:36:48 +08:00
func (f *Filter) isLegalData() bool {
val := reflect.ValueOf(f.data)
switch val.Kind() {
case reflect.Slice:
// slice 情况下,对字节数组进行特殊判断
var (
byteData []byte
ok bool
err error
)
2021-09-10 11:36:48 +08:00
if byteData, ok = f.data.([]byte); ok {
// 字节数组转map或者slice
2021-09-10 11:36:48 +08:00
if err = json.Unmarshal(byteData, &f.data); nil != err {
return false
}
return true
}
return true
case reflect.Map:
return true
case reflect.Struct:
// 结构体转为字符串处理
fallthrough
case reflect.Ptr:
// 指针
var err error
2021-09-10 11:36:48 +08:00
if f.data, err = util.StructToMap(f.data); nil != err {
return false
}
return true
default:
return false
}
}