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, ".") currentData := obj.data // 遍历路径直到到达最终部分 for i := 0; i < len(pathParts); i++ { key := pathParts[i] value, exists := currentData[key] if !exists { return defaultValue, nil } // 如果这是最后一个路径部分,返回值 if i == len(pathParts)-1 { return convertToJSONBaseObject(value), nil } // 否则继续深入嵌套对象 if nextMap, ok := value.(map[string]interface{}); ok { currentData = nextMap } else { // 如果路径还没结束但无法继续深入,返回默认值 return defaultValue, nil } } return defaultValue, 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 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 } } // 如果没有更多路径部分,直接返回元素 return convertToJSONBaseObject(element), nil } // 在JSONObject中设置属性 func setInJSONObject(obj *JSONObject, propertyPath string, value JSONBaseObject) error { pathParts := strings.Split(propertyPath, ".") currentData := obj.data // 遍历路径直到倒数第二个部分 for i := 0; i < len(pathParts)-1; i++ { key := pathParts[i] existingValue, exists := currentData[key] if !exists { // 如果不存在,创建一个新的map newMap := make(map[string]interface{}) currentData[key] = newMap currentData = newMap } else if nextMap, ok := existingValue.(map[string]interface{}); ok { // 如果已经是map,继续向下遍历 currentData = nextMap } else { // 如果不是map,替换为新的map newMap := make(map[string]interface{}) currentData[key] = newMap currentData = newMap } } // 设置最终值 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 } currentData[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 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 } } // 如果没有更多路径部分,直接设置数组元素 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 "" } }