github.com/alibabacloud-go/tea@v1.3.10/dara/xml.go (about) 1 package dara 2 3 import ( 4 "bytes" 5 "encoding/xml" 6 "fmt" 7 "reflect" 8 "strings" 9 10 v2 "github.com/clbanning/mxj/v2" 11 ) 12 13 func ToXML(obj map[string]interface{}) string { 14 return mapToXML(obj) 15 } 16 17 func ParseXml(val string, result interface{}) map[string]interface{} { 18 resp := make(map[string]interface{}) 19 20 start := getStartElement([]byte(val)) 21 if result == nil { 22 vm, err := v2.NewMapXml([]byte(val)) 23 if err != nil { 24 return nil 25 } 26 return vm 27 } 28 out, err := xmlUnmarshal([]byte(val), result) 29 if err != nil { 30 return resp 31 } 32 resp[start] = out 33 return resp 34 } 35 36 func mapToXML(val map[string]interface{}) string { 37 res := "" 38 for key, value := range val { 39 switch value.(type) { 40 case []interface{}: 41 for _, v := range value.([]interface{}) { 42 switch v.(type) { 43 case map[string]interface{}: 44 res += `<` + key + `>` 45 res += mapToXML(v.(map[string]interface{})) 46 res += `</` + key + `>` 47 default: 48 if fmt.Sprintf("%v", v) != `<nil>` { 49 res += `<` + key + `>` 50 res += fmt.Sprintf("%v", v) 51 res += `</` + key + `>` 52 } 53 } 54 } 55 case map[string]interface{}: 56 res += `<` + key + `>` 57 res += mapToXML(value.(map[string]interface{})) 58 res += `</` + key + `>` 59 default: 60 if fmt.Sprintf("%v", value) != `<nil>` { 61 res += `<` + key + `>` 62 res += fmt.Sprintf("%v", value) 63 res += `</` + key + `>` 64 } 65 } 66 } 67 return res 68 } 69 70 func getStartElement(body []byte) string { 71 d := xml.NewDecoder(bytes.NewReader(body)) 72 for { 73 tok, err := d.Token() 74 if err != nil { 75 return "" 76 } 77 if t, ok := tok.(xml.StartElement); ok { 78 return t.Name.Local 79 } 80 } 81 } 82 83 func xmlUnmarshal(body []byte, result interface{}) (interface{}, error) { 84 start := getStartElement(body) 85 dataValue := reflect.ValueOf(result).Elem() 86 dataType := dataValue.Type() 87 for i := 0; i < dataType.NumField(); i++ { 88 field := dataType.Field(i) 89 name, containsNameTag := field.Tag.Lookup("xml") 90 name = strings.Replace(name, ",omitempty", "", -1) 91 if containsNameTag { 92 if name == start { 93 realType := dataValue.Field(i).Type() 94 realValue := reflect.New(realType).Interface() 95 err := xml.Unmarshal(body, realValue) 96 if err != nil { 97 return nil, err 98 } 99 return realValue, nil 100 } 101 } 102 } 103 return nil, nil 104 }