init gen
This commit is contained in:
commit
b9a44c546e
|
|
@ -0,0 +1,141 @@
|
||||||
|
package gjson
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// JSONArray JSON Array 继承自JSONBaseObject,代表JSON中的数组类型
|
||||||
|
type JSONArray struct {
|
||||||
|
data []interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewJSONArray 创建一个新的JSONArray
|
||||||
|
func NewJSONArray() *JSONArray {
|
||||||
|
return &JSONArray{
|
||||||
|
data: make([]interface{}, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromJSON 从JSON字符串创建JSONArray
|
||||||
|
func (ja *JSONArray) FromJSON(jsonStr string) error {
|
||||||
|
var data []interface{}
|
||||||
|
if err := json.Unmarshal([]byte(jsonStr), &data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ja.data = data
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToJSON 将JSONArray转换为JSON字符串
|
||||||
|
func (ja *JSONArray) ToJSON() (string, error) {
|
||||||
|
bytes, err := json.Marshal(ja.data)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(bytes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromString 从字符串创建JSONArray(功能同FromJSON)
|
||||||
|
func (ja *JSONArray) FromString(str string) error {
|
||||||
|
return ja.FromJSON(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToString 将JSONArray转换为字符串(功能同ToJSON)
|
||||||
|
func (ja *JSONArray) ToString() (string, error) {
|
||||||
|
return ja.ToJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get 获取指定索引的元素
|
||||||
|
func (ja *JSONArray) Get(index int) (interface{}, bool) {
|
||||||
|
if index >= 0 && index < len(ja.data) {
|
||||||
|
return ja.data[index], true
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put 在指定索引设置元素
|
||||||
|
func (ja *JSONArray) Put(index int, value interface{}) error {
|
||||||
|
if index < 0 || index >= len(ja.data) {
|
||||||
|
return &InvalidIndexError{index, len(ja.data)}
|
||||||
|
}
|
||||||
|
ja.data[index] = extractValueFromJSONBaseObjectForArray(value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append 向数组末尾添加元素
|
||||||
|
func (ja *JSONArray) Append(value interface{}) {
|
||||||
|
ja.data = append(ja.data, extractValueFromJSONBaseObjectForArray(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 在指定位置插入元素
|
||||||
|
func (ja *JSONArray) Insert(index int, value interface{}) error {
|
||||||
|
if index < 0 || index > len(ja.data) {
|
||||||
|
return &InvalidIndexError{index, len(ja.data)}
|
||||||
|
}
|
||||||
|
ja.data = append(ja.data[:index], append([]interface{}{extractValueFromJSONBaseObjectForArray(value)}, ja.data[index:]...)...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove 删除指定索引的元素
|
||||||
|
func (ja *JSONArray) Remove(index int) error {
|
||||||
|
if index < 0 || index >= len(ja.data) {
|
||||||
|
return &InvalidIndexError{index, len(ja.data)}
|
||||||
|
}
|
||||||
|
ja.data = append(ja.data[:index], ja.data[index+1:]...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size 获取数组大小
|
||||||
|
func (ja *JSONArray) Size() int {
|
||||||
|
return len(ja.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty 检查数组是否为空
|
||||||
|
func (ja *JSONArray) IsEmpty() bool {
|
||||||
|
return len(ja.data) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetData 获取内部数据
|
||||||
|
func (ja *JSONArray) GetData() []interface{} {
|
||||||
|
return ja.data
|
||||||
|
}
|
||||||
|
|
||||||
|
// InvalidIndexError 索引越界错误
|
||||||
|
type InvalidIndexError struct {
|
||||||
|
index int
|
||||||
|
size int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *InvalidIndexError) Error() string {
|
||||||
|
return "index out of bounds: index " + strconv.Itoa(e.index) + " with size " + strconv.Itoa(e.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractValueFromJSONBaseObjectForArray 从JSONBaseObject中提取原始值用于数组
|
||||||
|
func extractValueFromJSONBaseObjectForArray(obj interface{}) interface{} {
|
||||||
|
switch v := obj.(type) {
|
||||||
|
case JSONBaseObject:
|
||||||
|
switch t := v.(type) {
|
||||||
|
case *JSONString:
|
||||||
|
return t.Value()
|
||||||
|
case *JSONNumber:
|
||||||
|
return t.Value()
|
||||||
|
case *JSONBool:
|
||||||
|
return t.Value()
|
||||||
|
case *JSONNull:
|
||||||
|
return t.Value()
|
||||||
|
case *JSONObject:
|
||||||
|
return t.data
|
||||||
|
case *JSONArray:
|
||||||
|
return t.data
|
||||||
|
default:
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
case *JSONObject:
|
||||||
|
return v.data
|
||||||
|
case *JSONArray:
|
||||||
|
return v.data
|
||||||
|
default:
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package gjson
|
||||||
|
|
||||||
|
// JSONBaseObject 抽象对象,代表所有能够进行JSON序列化和反序列化的对象
|
||||||
|
type JSONBaseObject interface {
|
||||||
|
ToJSON() (string, error)
|
||||||
|
FromJSON(jsonStr string) error
|
||||||
|
ToString() (string, error)
|
||||||
|
FromString(str string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSONValue 代表简单值对象,子类型包括:JSONString、JSONNumber、JSONBool、JSONNull
|
||||||
|
type JSONValue interface {
|
||||||
|
JSONBaseObject
|
||||||
|
Value() interface{}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
# GJson
|
||||||
|
|
||||||
|
实现一个通用的Golang Json对象库
|
||||||
|
|
||||||
|
## 对象模型
|
||||||
|
|
||||||
|
1. JSONBaseObject 抽象对象,代表所有能够进行JSON序列化和反序列化的对象
|
||||||
|
2. JSONObject JSON Object 继承自JSONBaseObject
|
||||||
|
3. JSONArray JSON Array 继承自JSONBaseObject 代表JSON中的数组类型
|
||||||
|
4. JSONValue 代表简单值对象,子类型包括:JSONString、JSONNumber、JSONBool、JSONNull
|
||||||
|
|
||||||
|
## 功能:
|
||||||
|
|
||||||
|
1. 序列化/反序列化:对象模型中提到的所有类型都应该实现toJson,fromJson,toString,fromString方法. string和json方法功能一致。
|
||||||
|
2. 对象属性操作功能,应该提供以下函数:
|
||||||
|
1. 获取属性值 getProperty(obj JSONBaseObject, propertyPath string, defaultValue JSONBaseObject)
|
||||||
|
2. 设置属性值 setProperty(obj JSONBaseObject, propertyPath string, value JSONBaseObject)
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.kingecg.top/kingecg/gjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("GJson 示例程序")
|
||||||
|
|
||||||
|
// 创建JSONObject
|
||||||
|
obj := gjson.NewJSONObject()
|
||||||
|
obj.Put("name", gjson.NewJSONString("张三").Value())
|
||||||
|
obj.Put("age", gjson.NewJSONNumber(25).Value())
|
||||||
|
obj.Put("student", gjson.NewJSONBool(false).Value())
|
||||||
|
|
||||||
|
// 创建嵌套对象
|
||||||
|
address := gjson.NewJSONObject()
|
||||||
|
address.Put("city", gjson.NewJSONString("北京").Value())
|
||||||
|
address.Put("zip", gjson.NewJSONNumber(100000).Value())
|
||||||
|
obj.Put("address", address.GetData()) // 使用GetData()方法
|
||||||
|
|
||||||
|
// 创建数组
|
||||||
|
arr := gjson.NewJSONArray()
|
||||||
|
arr.Append(gjson.NewJSONString("item1").Value())
|
||||||
|
arr.Append(gjson.NewJSONNumber(123).Value())
|
||||||
|
obj.Put("items", arr.GetData()) // 使用GetData()方法
|
||||||
|
|
||||||
|
// 序列化到JSON
|
||||||
|
jsonStr, _ := obj.ToJSON()
|
||||||
|
fmt.Printf("JSON对象: %s\n", jsonStr)
|
||||||
|
|
||||||
|
// 从JSON字符串创建对象
|
||||||
|
newObj := gjson.NewJSONObject()
|
||||||
|
newObj.FromJSON(jsonStr)
|
||||||
|
|
||||||
|
// 获取属性值
|
||||||
|
nameVal, _ := newObj.Get("name")
|
||||||
|
name := gjson.NewJSONString(fmt.Sprintf("%v", nameVal))
|
||||||
|
fmt.Printf("姓名: %s\n", name.Value())
|
||||||
|
|
||||||
|
// 测试嵌套属性
|
||||||
|
addressVal, _ := newObj.Get("address")
|
||||||
|
if addrMap, ok := addressVal.(map[string]interface{}); ok {
|
||||||
|
cityVal, exists := addrMap["city"]
|
||||||
|
if exists {
|
||||||
|
fmt.Printf("地址城市: %v\n", cityVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用GetProperty方法
|
||||||
|
defaultValue := gjson.NewJSONString("default")
|
||||||
|
propResult, _ := gjson.GetProperty(newObj, "name", defaultValue)
|
||||||
|
if str, ok := propResult.(*gjson.JSONString); ok {
|
||||||
|
fmt.Printf("通过GetProperty获取的姓名: %s\n", str.Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
propResult2, _ := gjson.GetProperty(newObj, "address.city", defaultValue)
|
||||||
|
if str, ok := propResult2.(*gjson.JSONString); ok {
|
||||||
|
fmt.Printf("通过GetProperty获取的城市: %s\n", str.Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置属性值
|
||||||
|
gjson.SetProperty(newObj, "address.city", gjson.NewJSONString("上海"))
|
||||||
|
modifiedProp, _ := gjson.GetProperty(newObj, "address.city", defaultValue)
|
||||||
|
if str, ok := modifiedProp.(*gjson.JSONString); ok {
|
||||||
|
fmt.Printf("修改后的城市: %s\n", str.Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建JSONArray并演示其用法
|
||||||
|
jsonArray := gjson.NewJSONArray()
|
||||||
|
jsonArray.Append(gjson.NewJSONString("first").Value())
|
||||||
|
jsonArray.Append(gjson.NewJSONNumber(42).Value())
|
||||||
|
|
||||||
|
nestedObj := gjson.NewJSONObject()
|
||||||
|
nestedObj.Put("nestedProp", gjson.NewJSONString("nestedValue").Value())
|
||||||
|
jsonArray.Append(nestedObj.GetData()) // 使用GetData()方法
|
||||||
|
|
||||||
|
arrayJson, _ := jsonArray.ToJSON()
|
||||||
|
fmt.Printf("JSON数组: %s\n", arrayJson)
|
||||||
|
|
||||||
|
// 访问数组元素
|
||||||
|
firstElement, _ := jsonArray.Get(0)
|
||||||
|
fmt.Printf("第一个元素: %v\n", firstElement)
|
||||||
|
|
||||||
|
// 访问嵌套对象
|
||||||
|
nestedValue, _ := gjson.GetProperty(jsonArray, "2.nestedProp", gjson.NewJSONString("default"))
|
||||||
|
if str, ok := nestedValue.(*gjson.JSONString); ok {
|
||||||
|
fmt.Printf("嵌套对象属性: %s\n", str.Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 演示各种值类型
|
||||||
|
nullValue := gjson.NewJSONNull()
|
||||||
|
nullStr, _ := nullValue.ToString()
|
||||||
|
fmt.Printf("空值: %s\n", nullStr)
|
||||||
|
|
||||||
|
boolValue := gjson.NewJSONBool(true)
|
||||||
|
boolStr, _ := boolValue.ToString()
|
||||||
|
fmt.Printf("布尔值: %s\n", boolStr)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
package gjson
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// JSONObject JSON Object 继承自JSONBaseObject
|
||||||
|
type JSONObject struct {
|
||||||
|
data map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewJSONObject 创建一个新的JSONObject
|
||||||
|
func NewJSONObject() *JSONObject {
|
||||||
|
return &JSONObject{
|
||||||
|
data: make(map[string]interface{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromJSON 从JSON字符串创建JSONObject
|
||||||
|
func (jo *JSONObject) FromJSON(jsonStr string) error {
|
||||||
|
var data map[string]interface{}
|
||||||
|
if err := json.Unmarshal([]byte(jsonStr), &data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
jo.data = data
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToJSON 将JSONObject转换为JSON字符串
|
||||||
|
func (jo *JSONObject) ToJSON() (string, error) {
|
||||||
|
bytes, err := json.Marshal(jo.data)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(bytes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromString 从字符串创建JSONObject(功能同FromJSON)
|
||||||
|
func (jo *JSONObject) FromString(str string) error {
|
||||||
|
return jo.FromJSON(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToString 将JSONObject转换为字符串(功能同ToJSON)
|
||||||
|
func (jo *JSONObject) ToString() (string, error) {
|
||||||
|
return jo.ToJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get 获取指定键的值
|
||||||
|
func (jo *JSONObject) Get(key string) (interface{}, bool) {
|
||||||
|
value, exists := jo.data[key]
|
||||||
|
return value, exists
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put 设置指定键的值,如果是JSONBaseObject则提取其值
|
||||||
|
func (jo *JSONObject) Put(key string, value interface{}) {
|
||||||
|
switch v := value.(type) {
|
||||||
|
case JSONBaseObject:
|
||||||
|
// 如果是JSONBaseObject,转换为实际值
|
||||||
|
jo.data[key] = extractValueFromJSONBaseObject(v)
|
||||||
|
case *JSONObject:
|
||||||
|
jo.data[key] = v.data
|
||||||
|
case *JSONArray:
|
||||||
|
jo.data[key] = v.data
|
||||||
|
default:
|
||||||
|
jo.data[key] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove 删除指定键
|
||||||
|
func (jo *JSONObject) Remove(key string) {
|
||||||
|
delete(jo.data, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keys 获取所有键
|
||||||
|
func (jo *JSONObject) Keys() []string {
|
||||||
|
keys := make([]string, 0, len(jo.data))
|
||||||
|
for k := range jo.data {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size 获取对象大小
|
||||||
|
func (jo *JSONObject) Size() int {
|
||||||
|
return len(jo.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty 检查是否为空
|
||||||
|
func (jo *JSONObject) IsEmpty() bool {
|
||||||
|
return len(jo.data) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainsKey 检查是否包含指定键
|
||||||
|
func (jo *JSONObject) ContainsKey(key string) bool {
|
||||||
|
_, exists := jo.data[key]
|
||||||
|
return exists
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetData 获取内部数据
|
||||||
|
func (jo *JSONObject) GetData() map[string]interface{} {
|
||||||
|
return jo.data
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractValueFromJSONBaseObject 从JSONBaseObject中提取原始值
|
||||||
|
func extractValueFromJSONBaseObject(obj JSONBaseObject) interface{} {
|
||||||
|
switch v := obj.(type) {
|
||||||
|
case *JSONString:
|
||||||
|
return v.Value()
|
||||||
|
case *JSONNumber:
|
||||||
|
return v.Value()
|
||||||
|
case *JSONBool:
|
||||||
|
return v.Value()
|
||||||
|
case *JSONNull:
|
||||||
|
return v.Value()
|
||||||
|
case *JSONObject:
|
||||||
|
return v.data
|
||||||
|
case *JSONArray:
|
||||||
|
return v.data
|
||||||
|
default:
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,252 @@
|
||||||
|
package gjson
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// getProperty 获取属性值
|
||||||
|
func GetProperty(obj JSONBaseObject, propertyPath string, defaultValue JSONBaseObject) (JSONBaseObject, error) {
|
||||||
|
// 首先尝试将obj转换为其实际类型
|
||||||
|
switch v := obj.(type) {
|
||||||
|
case *JSONObject:
|
||||||
|
return getFromJSONObject(v, propertyPath, defaultValue)
|
||||||
|
case *JSONArray:
|
||||||
|
return getFromJSONArray(v, propertyPath, defaultValue)
|
||||||
|
default:
|
||||||
|
// 如果是基础类型,直接返回默认值
|
||||||
|
return defaultValue, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setProperty 设置属性值
|
||||||
|
func SetProperty(obj JSONBaseObject, propertyPath string, value JSONBaseObject) error {
|
||||||
|
switch v := obj.(type) {
|
||||||
|
case *JSONObject:
|
||||||
|
return setInJSONObject(v, propertyPath, value)
|
||||||
|
case *JSONArray:
|
||||||
|
return setInJSONArray(v, propertyPath, value)
|
||||||
|
default:
|
||||||
|
// 不支持对基本值类型设置属性
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从JSONObject中获取属性
|
||||||
|
func getFromJSONObject(obj *JSONObject, propertyPath string, defaultValue JSONBaseObject) (JSONBaseObject, error) {
|
||||||
|
pathParts := strings.Split(propertyPath, ".")
|
||||||
|
currentObj := obj
|
||||||
|
|
||||||
|
// 遍历路径直到倒数第二个部分
|
||||||
|
for i := 0; i < len(pathParts)-1; i++ {
|
||||||
|
key := pathParts[i]
|
||||||
|
value, exists := currentObj.Get(key)
|
||||||
|
if !exists {
|
||||||
|
return defaultValue, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果路径中间部分不是JSONObject,则无法继续
|
||||||
|
if jsonObj, ok := value.(*JSONObject); ok {
|
||||||
|
currentObj = jsonObj
|
||||||
|
} else {
|
||||||
|
return defaultValue, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取最终值
|
||||||
|
finalKey := pathParts[len(pathParts)-1]
|
||||||
|
value, exists := currentObj.Get(finalKey)
|
||||||
|
if !exists {
|
||||||
|
return defaultValue, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据值的类型返回相应的JSONBaseObject
|
||||||
|
return convertToJSONBaseObject(value), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从JSONArray中获取属性
|
||||||
|
func getFromJSONArray(arr *JSONArray, propertyPath string, defaultValue JSONBaseObject) (JSONBaseObject, error) {
|
||||||
|
// 解析路径,支持数组索引
|
||||||
|
parts := strings.Split(propertyPath, ".")
|
||||||
|
|
||||||
|
// 第一部分应该是数组索引
|
||||||
|
indexStr := parts[0]
|
||||||
|
index, err := strconv.Atoi(indexStr)
|
||||||
|
if err != nil {
|
||||||
|
return defaultValue, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数组元素
|
||||||
|
element, exists := arr.Get(index)
|
||||||
|
if !exists {
|
||||||
|
return defaultValue, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有后续路径部分,说明要访问嵌套对象
|
||||||
|
if len(parts) > 1 {
|
||||||
|
remainingPath := strings.Join(parts[1:], ".")
|
||||||
|
|
||||||
|
// 检查元素类型并递归查找
|
||||||
|
switch elem := element.(type) {
|
||||||
|
case *JSONObject:
|
||||||
|
return getFromJSONObject(elem, remainingPath, defaultValue)
|
||||||
|
case *JSONArray:
|
||||||
|
return getFromJSONArray(elem, remainingPath, defaultValue)
|
||||||
|
default:
|
||||||
|
// 其他类型无法继续访问属性
|
||||||
|
return defaultValue, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有更多路径部分,直接返回元素
|
||||||
|
return convertToJSONBaseObject(element), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在JSONObject中设置属性
|
||||||
|
func setInJSONObject(obj *JSONObject, propertyPath string, value JSONBaseObject) error {
|
||||||
|
pathParts := strings.Split(propertyPath, ".")
|
||||||
|
currentObj := obj
|
||||||
|
|
||||||
|
// 遍历路径直到倒数第二个部分
|
||||||
|
for i := 0; i < len(pathParts)-1; i++ {
|
||||||
|
key := pathParts[i]
|
||||||
|
existingValue, exists := currentObj.Get(key)
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
// 如果不存在,创建一个新的JSONObject
|
||||||
|
newObj := NewJSONObject()
|
||||||
|
currentObj.Put(key, newObj)
|
||||||
|
currentObj = newObj
|
||||||
|
} else if jsonObj, ok := existingValue.(*JSONObject); ok {
|
||||||
|
// 如果已经是JSONObject,继续向下遍历
|
||||||
|
currentObj = jsonObj
|
||||||
|
} else {
|
||||||
|
// 如果不是JSONObject,替换为新的JSONObject
|
||||||
|
newObj := NewJSONObject()
|
||||||
|
currentObj.Put(key, newObj)
|
||||||
|
currentObj = newObj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置最终值
|
||||||
|
finalKey := pathParts[len(pathParts)-1]
|
||||||
|
|
||||||
|
// 将JSONBaseObject转换为interface{}
|
||||||
|
var interfaceValue interface{}
|
||||||
|
switch v := value.(type) {
|
||||||
|
case *JSONObject:
|
||||||
|
interfaceValue = v.data
|
||||||
|
case *JSONArray:
|
||||||
|
interfaceValue = v.data
|
||||||
|
case *JSONString:
|
||||||
|
interfaceValue = v.Value()
|
||||||
|
case *JSONNumber:
|
||||||
|
interfaceValue = v.Value()
|
||||||
|
case *JSONBool:
|
||||||
|
interfaceValue = v.Value()
|
||||||
|
case *JSONNull:
|
||||||
|
interfaceValue = v.Value()
|
||||||
|
default:
|
||||||
|
interfaceValue = v
|
||||||
|
}
|
||||||
|
|
||||||
|
currentObj.Put(finalKey, interfaceValue)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在JSONArray中设置属性
|
||||||
|
func setInJSONArray(arr *JSONArray, propertyPath string, value JSONBaseObject) error {
|
||||||
|
// 解析路径,第一部分应该是数组索引
|
||||||
|
parts := strings.Split(propertyPath, ".")
|
||||||
|
|
||||||
|
indexStr := parts[0]
|
||||||
|
index, err := strconv.Atoi(indexStr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数组元素
|
||||||
|
element, exists := arr.Get(index)
|
||||||
|
if !exists {
|
||||||
|
return nil // 索引不存在
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有后续路径部分,说明要设置嵌套对象
|
||||||
|
if len(parts) > 1 {
|
||||||
|
remainingPath := strings.Join(parts[1:], ".")
|
||||||
|
|
||||||
|
// 检查元素类型并递归设置
|
||||||
|
switch elem := element.(type) {
|
||||||
|
case *JSONObject:
|
||||||
|
return SetProperty(elem, remainingPath, value)
|
||||||
|
case *JSONArray:
|
||||||
|
return SetProperty(elem, remainingPath, value)
|
||||||
|
default:
|
||||||
|
// 其他类型无法设置属性
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有更多路径部分,直接设置数组元素
|
||||||
|
var interfaceValue interface{}
|
||||||
|
switch v := value.(type) {
|
||||||
|
case *JSONObject:
|
||||||
|
interfaceValue = v.data
|
||||||
|
case *JSONArray:
|
||||||
|
interfaceValue = v.data
|
||||||
|
case *JSONString:
|
||||||
|
interfaceValue = v.Value()
|
||||||
|
case *JSONNumber:
|
||||||
|
interfaceValue = v.Value()
|
||||||
|
case *JSONBool:
|
||||||
|
interfaceValue = v.Value()
|
||||||
|
case *JSONNull:
|
||||||
|
interfaceValue = v.Value()
|
||||||
|
default:
|
||||||
|
interfaceValue = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr.Put(index, interfaceValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将interface{}转换为适当的JSONBaseObject
|
||||||
|
func convertToJSONBaseObject(value interface{}) JSONBaseObject {
|
||||||
|
switch v := value.(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
jsonObj := NewJSONObject()
|
||||||
|
jsonObj.data = v
|
||||||
|
return jsonObj
|
||||||
|
case []interface{}:
|
||||||
|
jsonArr := NewJSONArray()
|
||||||
|
jsonArr.data = v
|
||||||
|
return jsonArr
|
||||||
|
case string:
|
||||||
|
return NewJSONString(v)
|
||||||
|
case float64:
|
||||||
|
return NewJSONNumber(v)
|
||||||
|
case bool:
|
||||||
|
return NewJSONBool(v)
|
||||||
|
case nil:
|
||||||
|
return NewJSONNull()
|
||||||
|
default:
|
||||||
|
// 默认转换为字符串
|
||||||
|
return NewJSONString(stringify(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// stringify 将任意值转换为字符串表示
|
||||||
|
func stringify(value interface{}) string {
|
||||||
|
if value == nil {
|
||||||
|
return "null"
|
||||||
|
}
|
||||||
|
switch v := value.(type) {
|
||||||
|
case string:
|
||||||
|
return v
|
||||||
|
case float64:
|
||||||
|
return strconv.FormatFloat(v, 'f', -1, 64)
|
||||||
|
case bool:
|
||||||
|
return strconv.FormatBool(v)
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,185 @@
|
||||||
|
package gjson
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// JSONString 字符串值类型
|
||||||
|
type JSONString struct {
|
||||||
|
value string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewJSONString 创建新的JSONString实例
|
||||||
|
func NewJSONString(value string) *JSONString {
|
||||||
|
return &JSONString{value: value}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value 返回实际的字符串值
|
||||||
|
func (js *JSONString) Value() interface{} {
|
||||||
|
return js.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToJSON 返回JSON格式的字符串表示
|
||||||
|
func (js *JSONString) ToJSON() (string, error) {
|
||||||
|
bytes, err := json.Marshal(js.value)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(bytes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromJSON 从JSON字符串初始化
|
||||||
|
func (js *JSONString) FromJSON(jsonStr string) error {
|
||||||
|
var str string
|
||||||
|
if err := json.Unmarshal([]byte(jsonStr), &str); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
js.value = str
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToString 返回字符串表示
|
||||||
|
func (js *JSONString) ToString() (string, error) {
|
||||||
|
return js.value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromString 从字符串初始化
|
||||||
|
func (js *JSONString) FromString(str string) error {
|
||||||
|
js.value = str
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSONNumber 数字值类型
|
||||||
|
type JSONNumber struct {
|
||||||
|
value float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewJSONNumber 创建新的JSONNumber实例
|
||||||
|
func NewJSONNumber(value float64) *JSONNumber {
|
||||||
|
return &JSONNumber{value: value}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value 返回实际的数字值
|
||||||
|
func (jn *JSONNumber) Value() interface{} {
|
||||||
|
return jn.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToJSON 返回JSON格式的数字表示
|
||||||
|
func (jn *JSONNumber) ToJSON() (string, error) {
|
||||||
|
return strconv.FormatFloat(jn.value, 'f', -1, 64), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromJSON 从JSON字符串初始化
|
||||||
|
func (jn *JSONNumber) FromJSON(jsonStr string) error {
|
||||||
|
var num float64
|
||||||
|
if err := json.Unmarshal([]byte(jsonStr), &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
jn.value = num
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToString 返回字符串表示
|
||||||
|
func (jn *JSONNumber) ToString() (string, error) {
|
||||||
|
return strconv.FormatFloat(jn.value, 'f', -1, 64), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromString 从字符串初始化
|
||||||
|
func (jn *JSONNumber) FromString(str string) error {
|
||||||
|
num, err := strconv.ParseFloat(str, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
jn.value = num
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSONBool 布尔值类型
|
||||||
|
type JSONBool struct {
|
||||||
|
value bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewJSONBool 创建新的JSONBool实例
|
||||||
|
func NewJSONBool(value bool) *JSONBool {
|
||||||
|
return &JSONBool{value: value}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value 返回实际的布尔值
|
||||||
|
func (jb *JSONBool) Value() interface{} {
|
||||||
|
return jb.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToJSON 返回JSON格式的布尔值表示
|
||||||
|
func (jb *JSONBool) ToJSON() (string, error) {
|
||||||
|
return strconv.FormatBool(jb.value), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromJSON 从JSON字符串初始化
|
||||||
|
func (jb *JSONBool) FromJSON(jsonStr string) error {
|
||||||
|
var b bool
|
||||||
|
if err := json.Unmarshal([]byte(jsonStr), &b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
jb.value = b
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToString 返回字符串表示
|
||||||
|
func (jb *JSONBool) ToString() (string, error) {
|
||||||
|
return strconv.FormatBool(jb.value), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromString 从字符串初始化
|
||||||
|
func (jb *JSONBool) FromString(str string) error {
|
||||||
|
b, err := strconv.ParseBool(str)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
jb.value = b
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSONNull 空值类型
|
||||||
|
type JSONNull struct{}
|
||||||
|
|
||||||
|
// NewJSONNull 创建新的JSONNull实例
|
||||||
|
func NewJSONNull() *JSONNull {
|
||||||
|
return &JSONNull{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value 返回null值
|
||||||
|
func (jn *JSONNull) Value() interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToJSON 返回JSON格式的null表示
|
||||||
|
func (jn *JSONNull) ToJSON() (string, error) {
|
||||||
|
return "null", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromJSON 从JSON字符串初始化
|
||||||
|
func (jn *JSONNull) FromJSON(jsonStr string) error {
|
||||||
|
var val interface{}
|
||||||
|
if err := json.Unmarshal([]byte(jsonStr), &val); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if val != nil {
|
||||||
|
return fmt.Errorf("expected null, got %v", val)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToString 返回字符串表示
|
||||||
|
func (jn *JSONNull) ToString() (string, error) {
|
||||||
|
return "null", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromString 从字符串初始化
|
||||||
|
func (jn *JSONNull) FromString(str string) error {
|
||||||
|
if str != "null" {
|
||||||
|
return fmt.Errorf("expected 'null', got '%s'", str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue