```
feat(gjson): 添加Stringify功能并优化GetProperty/SetProperty实现 添加了Stringify、PrettyPrint和Compact函数,用于将JSONBaseObject 转换为格式化的JSON字符串。同时优化了GetProperty和SetProperty函数的 内部实现,改进了嵌套对象的访问逻辑,并更新了example/main.go以演示 新功能的使用方法。 ```
This commit is contained in:
parent
b9a44c546e
commit
7ee90f3a18
|
|
@ -30,6 +30,18 @@ func main() {
|
|||
jsonStr, _ := obj.ToJSON()
|
||||
fmt.Printf("JSON对象: %s\n", jsonStr)
|
||||
|
||||
// 使用Stringify函数
|
||||
stringified, _ := gjson.Stringify(obj)
|
||||
fmt.Printf("Stringify结果: %s\n", stringified)
|
||||
|
||||
// 使用PrettyPrint格式化输出
|
||||
pretty, _ := gjson.PrettyPrint(obj)
|
||||
fmt.Printf("格式化输出:\n%s\n", pretty)
|
||||
|
||||
// 使用Compact函数
|
||||
compact, _ := gjson.Compact(obj)
|
||||
fmt.Printf("紧凑格式: %s\n", compact)
|
||||
|
||||
// 从JSON字符串创建对象
|
||||
newObj := gjson.NewJSONObject()
|
||||
newObj.FromJSON(jsonStr)
|
||||
|
|
@ -79,6 +91,10 @@ func main() {
|
|||
arrayJson, _ := jsonArray.ToJSON()
|
||||
fmt.Printf("JSON数组: %s\n", arrayJson)
|
||||
|
||||
// 使用Stringify格式化数组
|
||||
arrayStringified, _ := gjson.Stringify(jsonArray, " ")
|
||||
fmt.Printf("格式化数组:\n%s\n", arrayStringified)
|
||||
|
||||
// 访问数组元素
|
||||
firstElement, _ := jsonArray.Get(0)
|
||||
fmt.Printf("第一个元素: %v\n", firstElement)
|
||||
|
|
@ -89,12 +105,20 @@ func main() {
|
|||
fmt.Printf("嵌套对象属性: %s\n", str.Value())
|
||||
}
|
||||
|
||||
// 演示各种值类型
|
||||
// 演示各种值类型的Stringify
|
||||
nullValue := gjson.NewJSONNull()
|
||||
nullStr, _ := nullValue.ToString()
|
||||
fmt.Printf("空值: %s\n", nullStr)
|
||||
nullStr, _ := gjson.Stringify(nullValue)
|
||||
fmt.Printf("空值Stringify: %s\n", nullStr)
|
||||
|
||||
boolValue := gjson.NewJSONBool(true)
|
||||
boolStr, _ := boolValue.ToString()
|
||||
fmt.Printf("布尔值: %s\n", boolStr)
|
||||
boolStr, _ := gjson.Stringify(boolValue)
|
||||
fmt.Printf("布尔值Stringify: %s\n", boolStr)
|
||||
|
||||
numValue := gjson.NewJSONNumber(42.5)
|
||||
numStr, _ := gjson.Stringify(numValue)
|
||||
fmt.Printf("数字Stringify: %s\n", numStr)
|
||||
|
||||
strValue := gjson.NewJSONString("hello world")
|
||||
strStr, _ := gjson.Stringify(strValue)
|
||||
fmt.Printf("字符串Stringify: %s\n", strStr)
|
||||
}
|
||||
84
property.go
84
property.go
|
|
@ -5,7 +5,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// getProperty 获取属性值
|
||||
// GetProperty 获取属性值
|
||||
func GetProperty(obj JSONBaseObject, propertyPath string, defaultValue JSONBaseObject) (JSONBaseObject, error) {
|
||||
// 首先尝试将obj转换为其实际类型
|
||||
switch v := obj.(type) {
|
||||
|
|
@ -19,7 +19,7 @@ func GetProperty(obj JSONBaseObject, propertyPath string, defaultValue JSONBaseO
|
|||
}
|
||||
}
|
||||
|
||||
// setProperty 设置属性值
|
||||
// SetProperty 设置属性值
|
||||
func SetProperty(obj JSONBaseObject, propertyPath string, value JSONBaseObject) error {
|
||||
switch v := obj.(type) {
|
||||
case *JSONObject:
|
||||
|
|
@ -35,33 +35,31 @@ func SetProperty(obj JSONBaseObject, propertyPath string, value JSONBaseObject)
|
|||
// 从JSONObject中获取属性
|
||||
func getFromJSONObject(obj *JSONObject, propertyPath string, defaultValue JSONBaseObject) (JSONBaseObject, error) {
|
||||
pathParts := strings.Split(propertyPath, ".")
|
||||
currentObj := obj
|
||||
currentData := obj.data
|
||||
|
||||
// 遍历路径直到倒数第二个部分
|
||||
for i := 0; i < len(pathParts)-1; i++ {
|
||||
// 遍历路径直到到达最终部分
|
||||
for i := 0; i < len(pathParts); i++ {
|
||||
key := pathParts[i]
|
||||
value, exists := currentObj.Get(key)
|
||||
value, exists := currentData[key]
|
||||
if !exists {
|
||||
return defaultValue, nil
|
||||
}
|
||||
|
||||
// 如果路径中间部分不是JSONObject,则无法继续
|
||||
if jsonObj, ok := value.(*JSONObject); ok {
|
||||
currentObj = jsonObj
|
||||
// 如果这是最后一个路径部分,返回值
|
||||
if i == len(pathParts)-1 {
|
||||
return convertToJSONBaseObject(value), nil
|
||||
}
|
||||
|
||||
// 否则继续深入嵌套对象
|
||||
if nextMap, ok := value.(map[string]interface{}); ok {
|
||||
currentData = nextMap
|
||||
} else {
|
||||
// 如果路径还没结束但无法继续深入,返回默认值
|
||||
return defaultValue, nil
|
||||
}
|
||||
}
|
||||
|
||||
// 获取最终值
|
||||
finalKey := pathParts[len(pathParts)-1]
|
||||
value, exists := currentObj.Get(finalKey)
|
||||
if !exists {
|
||||
return defaultValue, nil
|
||||
}
|
||||
|
||||
// 根据值的类型返回相应的JSONBaseObject
|
||||
return convertToJSONBaseObject(value), nil
|
||||
return defaultValue, nil
|
||||
}
|
||||
|
||||
// 从JSONArray中获取属性
|
||||
|
|
@ -88,10 +86,14 @@ func getFromJSONArray(arr *JSONArray, propertyPath string, defaultValue JSONBase
|
|||
|
||||
// 检查元素类型并递归查找
|
||||
switch elem := element.(type) {
|
||||
case *JSONObject:
|
||||
return getFromJSONObject(elem, remainingPath, defaultValue)
|
||||
case *JSONArray:
|
||||
return getFromJSONArray(elem, remainingPath, defaultValue)
|
||||
case map[string]interface{}:
|
||||
// 创建临时JSONObject用于查找
|
||||
tempObj := &JSONObject{data: elem}
|
||||
return getFromJSONObject(tempObj, remainingPath, defaultValue)
|
||||
case []interface{}:
|
||||
// 创建临时JSONArray用于查找
|
||||
tempArr := &JSONArray{data: elem}
|
||||
return getFromJSONArray(tempArr, remainingPath, defaultValue)
|
||||
default:
|
||||
// 其他类型无法继续访问属性
|
||||
return defaultValue, nil
|
||||
|
|
@ -105,26 +107,26 @@ func getFromJSONArray(arr *JSONArray, propertyPath string, defaultValue JSONBase
|
|||
// 在JSONObject中设置属性
|
||||
func setInJSONObject(obj *JSONObject, propertyPath string, value JSONBaseObject) error {
|
||||
pathParts := strings.Split(propertyPath, ".")
|
||||
currentObj := obj
|
||||
currentData := obj.data
|
||||
|
||||
// 遍历路径直到倒数第二个部分
|
||||
for i := 0; i < len(pathParts)-1; i++ {
|
||||
key := pathParts[i]
|
||||
existingValue, exists := currentObj.Get(key)
|
||||
existingValue, exists := currentData[key]
|
||||
|
||||
if !exists {
|
||||
// 如果不存在,创建一个新的JSONObject
|
||||
newObj := NewJSONObject()
|
||||
currentObj.Put(key, newObj)
|
||||
currentObj = newObj
|
||||
} else if jsonObj, ok := existingValue.(*JSONObject); ok {
|
||||
// 如果已经是JSONObject,继续向下遍历
|
||||
currentObj = jsonObj
|
||||
// 如果不存在,创建一个新的map
|
||||
newMap := make(map[string]interface{})
|
||||
currentData[key] = newMap
|
||||
currentData = newMap
|
||||
} else if nextMap, ok := existingValue.(map[string]interface{}); ok {
|
||||
// 如果已经是map,继续向下遍历
|
||||
currentData = nextMap
|
||||
} else {
|
||||
// 如果不是JSONObject,替换为新的JSONObject
|
||||
newObj := NewJSONObject()
|
||||
currentObj.Put(key, newObj)
|
||||
currentObj = newObj
|
||||
// 如果不是map,替换为新的map
|
||||
newMap := make(map[string]interface{})
|
||||
currentData[key] = newMap
|
||||
currentData = newMap
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +152,7 @@ func setInJSONObject(obj *JSONObject, propertyPath string, value JSONBaseObject)
|
|||
interfaceValue = v
|
||||
}
|
||||
|
||||
currentObj.Put(finalKey, interfaceValue)
|
||||
currentData[finalKey] = interfaceValue
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -177,10 +179,12 @@ func setInJSONArray(arr *JSONArray, propertyPath string, value JSONBaseObject) e
|
|||
|
||||
// 检查元素类型并递归设置
|
||||
switch elem := element.(type) {
|
||||
case *JSONObject:
|
||||
return SetProperty(elem, remainingPath, value)
|
||||
case *JSONArray:
|
||||
return SetProperty(elem, remainingPath, value)
|
||||
case map[string]interface{}:
|
||||
tempObj := &JSONObject{data: elem}
|
||||
return SetProperty(tempObj, remainingPath, value)
|
||||
case []interface{}:
|
||||
tempArr := &JSONArray{data: elem}
|
||||
return SetProperty(tempArr, remainingPath, value)
|
||||
default:
|
||||
// 其他类型无法设置属性
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
package gjson
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// Stringify 将JSONBaseObject转换为格式化的JSON字符串
|
||||
// 类似于JavaScript中的JSON.stringify函数
|
||||
func Stringify(obj JSONBaseObject, space ...string) (string, error) {
|
||||
var indent string
|
||||
if len(space) > 0 {
|
||||
indent = space[0]
|
||||
} else {
|
||||
indent = "" // 默认无缩进
|
||||
}
|
||||
|
||||
// 根据不同的对象类型进行处理
|
||||
switch v := obj.(type) {
|
||||
case *JSONObject:
|
||||
if indent != "" {
|
||||
// 格式化带缩进的JSON
|
||||
bytes, err := json.MarshalIndent(v.data, "", indent)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
} else {
|
||||
// 紧凑型JSON
|
||||
bytes, err := json.Marshal(v.data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
}
|
||||
case *JSONArray:
|
||||
if indent != "" {
|
||||
// 格式化带缩进的JSON
|
||||
bytes, err := json.MarshalIndent(v.data, "", indent)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
} else {
|
||||
// 紧凑型JSON
|
||||
bytes, err := json.Marshal(v.data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
}
|
||||
case *JSONString:
|
||||
return v.ToJSON()
|
||||
case *JSONNumber:
|
||||
return v.ToJSON()
|
||||
case *JSONBool:
|
||||
return v.ToJSON()
|
||||
case *JSONNull:
|
||||
return v.ToJSON()
|
||||
default:
|
||||
// 如果是其他类型,尝试转换为JSON
|
||||
bytes, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
}
|
||||
}
|
||||
|
||||
// StringifySimple 简单的字符串化函数,将任何值转换为JSON字符串
|
||||
func StringifySimple(value interface{}, space ...string) (string, error) {
|
||||
var indent string
|
||||
if len(space) > 0 {
|
||||
indent = space[0]
|
||||
} else {
|
||||
indent = "" // 默认无缩进
|
||||
}
|
||||
|
||||
if indent != "" {
|
||||
bytes, err := json.MarshalIndent(value, "", indent)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
} else {
|
||||
bytes, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
}
|
||||
}
|
||||
|
||||
// PrettyPrint 格式化打印JSON对象
|
||||
func PrettyPrint(obj JSONBaseObject) (string, error) {
|
||||
return Stringify(obj, " ") // 使用两个空格作为缩进
|
||||
}
|
||||
|
||||
// Compact 将JSON对象转换为紧凑格式(无多余空白字符)
|
||||
func Compact(obj JSONBaseObject) (string, error) {
|
||||
return Stringify(obj) // 无缩进的格式
|
||||
}
|
||||
Loading…
Reference in New Issue