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 "" } }