支持从json -> xml的转换
This commit is contained in:
parent
cd85d80da6
commit
f9024b9498
@ -67,8 +67,9 @@ func (b *builderImpl) AddField(name string, pkg string, typ any, tag string, ano
|
|||||||
tag = cfgTag
|
tag = cfgTag
|
||||||
} else {
|
} else {
|
||||||
if len(tag) == 0 {
|
if len(tag) == 0 {
|
||||||
|
arr := strings.Split(strings.TrimSuffix(name, ".[]"), ".")
|
||||||
// 没指定tag, 字段名称作为tag名称
|
// 没指定tag, 字段名称作为tag名称
|
||||||
tag = strings.ReplaceAll(`json:"{TAG_NAME}" xml:"{TAG_NAME}" toml:"{TAG_NAME}" yaml:"{TAG_NAME}" ini:"{TAG_NAME}"`, "{TAG_NAME}", name)
|
tag = strings.ReplaceAll(`json:"{TAG_NAME}" xml:"{TAG_NAME}" toml:"{TAG_NAME}" yaml:"{TAG_NAME}" ini:"{TAG_NAME}"`, "{TAG_NAME}", arr[len(arr)-1])
|
||||||
// tag = fmt.Sprintf(`json:"%s"`, name)
|
// tag = fmt.Sprintf(`json:"%s"`, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
go.mod
2
go.mod
@ -10,7 +10,7 @@ require (
|
|||||||
require (
|
require (
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250425024726-cc17224cb995 // indirect
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250425024726-cc17224cb995 // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
|
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250426132259-73cf1be49c7f // indirect
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250428041157-135850ee8a58 // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect
|
||||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -10,6 +10,8 @@ git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd h1:q7G
|
|||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs=
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs=
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250426132259-73cf1be49c7f h1:7QgAcGnmVEVyIPeWH0ZkQN/jpzklYXsKCenTR2GpxbE=
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250426132259-73cf1be49c7f h1:7QgAcGnmVEVyIPeWH0ZkQN/jpzklYXsKCenTR2GpxbE=
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250426132259-73cf1be49c7f/go.mod h1:Ig3GZC2hJDkQp7F8Tm53GvMWLh9bdbbauow/vxGO4YA=
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250426132259-73cf1be49c7f/go.mod h1:Ig3GZC2hJDkQp7F8Tm53GvMWLh9bdbbauow/vxGO4YA=
|
||||||
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250428041157-135850ee8a58 h1:fTkmucGaUoKocoX+ASM4AnwsAVJOtOOLUFSqA+uwVzg=
|
||||||
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250428041157-135850ee8a58/go.mod h1:Ig3GZC2hJDkQp7F8Tm53GvMWLh9bdbbauow/vxGO4YA=
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI=
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI=
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250302133417-c1588abcb436 h1:SM4zc54W2wmM72+4pMNQ8iS371H6lj4J8rj8KJKf7pw=
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250302133417-c1588abcb436 h1:SM4zc54W2wmM72+4pMNQ8iS371H6lj4J8rj8KJKf7pw=
|
||||||
|
136
wrapper/json.go
Normal file
136
wrapper/json.go
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
// Package wrapper ...
|
||||||
|
//
|
||||||
|
// Description : wrapper ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-04-28 15:32
|
||||||
|
package wrapper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"errors"
|
||||||
|
dynamicstruct "git.zhangdeman.cn/zhangdeman/dynamic-struct"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewJson(sourceData string) (*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")
|
||||||
|
}
|
||||||
|
oj := &ownJson{
|
||||||
|
sourceData: sourceData,
|
||||||
|
gjsonResult: gjsonRes,
|
||||||
|
structBuilder: dynamicstruct.NewStruct(nil),
|
||||||
|
}
|
||||||
|
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 // 解析的结构体值
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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{}, `json:"-" xml:"XmlData"`, 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
|
||||||
|
}
|
22
wrapper/json_test.go
Normal file
22
wrapper/json_test.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Package wrapper ...
|
||||||
|
//
|
||||||
|
// Description : wrapper ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-04-28 16:59
|
||||||
|
package wrapper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewJson(t *testing.T) {
|
||||||
|
sourceData := `{"name": "test", "age":18,"company":{"address": "Beijing", "name":"lala"},"index":[1,2,3,4], "deep":[{"name":"a"}]}`
|
||||||
|
instance, iErr := NewJson(sourceData)
|
||||||
|
fmt.Println(iErr)
|
||||||
|
res, err := instance.Marshal("xml")
|
||||||
|
fmt.Println(err)
|
||||||
|
fmt.Println(string(res))
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user