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