package pkg import ( "bytes" "encoding/json" "fmt" "gitea.cdlsxd.cn/self-tools/tysk/tysk_constant" "github.com/clbanning/mxj" "reflect" "strconv" "strings" ) // XmlRequest 定义请求结构 type XmlRequest struct { Action tysk_constant.RequestCode `xml:"action"` UserName string `xml:"userName"` ExtraFields map[string]interface{} `xml:"-"` // 忽略此字段,手动处理 } // MarshalToXML 将XmlRequest转换为指定格式的XML字节流 func (req XmlRequest) MarshalToXML() ([]byte, error) { var buf bytes.Buffer // 写入XML声明 buf.WriteString(`` + "\n") buf.WriteString("\n") // 写入基本字段 buf.WriteString(fmt.Sprintf("%s\n", req.Action)) buf.WriteString(fmt.Sprintf("%s\n", req.UserName)) // 处理ExtraFields for key, value := range req.ExtraFields { switch v := value.(type) { case []map[string]interface{}: // 处理列表数据 buf.WriteString(fmt.Sprintf("\n", key)) for _, row := range v { if len(row) == 0 { continue } buf.WriteString("\n") for rowKey, rowValue := range row { buf.WriteString(fmt.Sprintf("<%s>%s\n", rowKey, ToString(rowValue), rowKey)) } buf.WriteString("\n") } buf.WriteString("\n") case []string: // 处理列表数据 buf.WriteString(fmt.Sprintf("\n", key)) buf.WriteString("\n") for _, row := range v { buf.WriteString(fmt.Sprintf("<%s>%s\n", key, row, key)) } buf.WriteString("\n") buf.WriteString("\n") case []interface{}: // 处理列表数据 buf.WriteString(fmt.Sprintf("\n", key)) for _, row := range v { buf.WriteString("\n") if vmap, isMapList := row.(map[string]interface{}); isMapList { for rowKey, rowValue := range vmap { buf.WriteString(fmt.Sprintf("<%s>%v\n", rowKey, rowValue, rowKey)) } } buf.WriteString("\n") } buf.WriteString("\n") case map[string]interface{}: // 处理列表数据 buf.WriteString(fmt.Sprintf("\n", key)) for rowKey, row := range v { switch row.(type) { case []interface{}: for _, rowValue := range row.([]interface{}) { buf.WriteString("\n") buf.WriteString(fmt.Sprintf("<%s>%s\n", rowKey, rowValue, rowKey)) buf.WriteString("\n") } default: buf.WriteString("\n") buf.WriteString(fmt.Sprintf("<%s>%s\n", key, row, key)) buf.WriteString("\n") } } buf.WriteString("\n") // 可以根据需要添加其他类型的处理 default: buf.WriteString(fmt.Sprintf("<%s>%s\n", key, ToString(v), key)) } } buf.WriteString("") return buf.Bytes(), nil } func XMLToByte(xmlBytes []byte) ([]byte, error) { // 去掉XML声明 if idx := bytes.Index(xmlBytes, []byte("?>")); idx != -1 { xmlBytes = xmlBytes[idx+2:] } // 解析XML mv, err := mxj.NewMapXml(xmlBytes) if err != nil { return nil, fmt.Errorf("XML 解析失败: %v", err) } // 获取stream节点 stream, ok := mv["stream"].(map[string]interface{}) if !ok { return nil, fmt.Errorf("无效的XML结构: 缺少stream节点") } // 处理list节点 if lists, ok := stream["list"]; ok { switch lists.(type) { case []interface{}: for _, listItem := range lists.([]interface{}) { if listMap, ok := listItem.(map[string]interface{}); ok { // 获取name属性 if name, ok := listMap["-name"].(string); ok && name != "" { // 用name作为key,替换原来的list数组 if rowList, ok := listMap["row"].(map[string]interface{}); ok { stream[name] = []map[string]interface{}{rowList} } else { stream[name] = listMap["row"] } } } } case map[string]interface{}: listMap := lists.(map[string]interface{}) if name, ok := listMap["-name"].(string); ok && name != "" { // 用name作为key,替换原来的list数组 if rowList, ok := listMap["row"].(map[string]interface{}); ok { stream[name] = []map[string]interface{}{rowList} } else { stream[name] = listMap["row"] } } default: } // 删除原始的list节点 delete(stream, "list") } // 转换为JSON jsonData, err := json.Marshal(stream) if err != nil { return nil, fmt.Errorf("JSON序列化失败: %v", err) } return jsonData, nil } func SliceToMap(list []interface{}) (listMap []map[string]interface{}) { listMap = make([]map[string]interface{}, len(list)) //for _, accountNo := range list { // listMap = append(list, map[string]interface{}{"accountNo": accountNo}) //} return } func IsStruct(v interface{}) bool { if v == nil { return false } t := reflect.TypeOf(v) if t.Kind() == reflect.Ptr { t = t.Elem() } return t.Kind() == reflect.Struct } // StructToMap 将一个struct转换为map[string]interface{} func StructToMap(obj interface{}) map[string]interface{} { // 获取obj的类型 val := reflect.ValueOf(obj) if val.Kind() == reflect.Ptr { val = val.Elem() } // 确保obj是一个struct if val.Kind() != reflect.Struct { return nil } // 创建一个map来保存结果 data := make(map[string]interface{}) // 遍历struct的字段 for i := 0; i < val.NumField(); i++ { // 获取字段的类型和值 valueField := val.Field(i) typeField := val.Type().Field(i) jsonTag := typeField.Tag.Get("json") if idx := strings.Index(jsonTag, ","); idx != -1 { // 如果有逗号,则取逗号之前的部分 jsonTag = jsonTag[:idx] } // 忽略未导出的字段(字段名首字母小写) if !typeField.IsExported() { continue } // 将字段名和值添加到map中 data[jsonTag] = valueField.Interface() } return data } func ToString(v interface{}) string { switch v := v.(type) { case int: return strconv.Itoa(v) case float64: return strconv.FormatFloat(v, 'f', -1, 64) case bool: return strconv.FormatBool(v) case string: return v case fmt.Stringer: // 实现了 String() 接口的类型 return v.String() default: return fmt.Sprintf("%v", v) // 其他类型 fallback } } // BuildNestedMap 通用方法:根据动态路径(如 "userDataList.rcptNum")构造嵌套 map func BuildNestedMap(path string, value interface{}) (map[string]interface{}, string) { keys := strings.Split(path, ".") result := make(map[string]interface{}) current := result // 迭代处理每一级 key for i, key := range keys { if i == len(keys)-1 { // 最后一层,赋值 current[key] = value } else { // 非最后一层,创建嵌套 map newMap := make(map[string]interface{}) current[key] = newMap current = newMap } } return result, keys[0] }