...

Source file src/github.com/alibabacloud-go/tea-xml/service/service.go

Documentation: github.com/alibabacloud-go/tea-xml/service

     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