package xmlutil

import (
	
	
	
	
	
	
	
	
	

	
	
)
UnmarshalXMLError unmarshals the XML error from the stream into the value type specified. The value must be a pointer. If the message fails to unmarshal, the message content will be included in the returned error as a awserr.UnmarshalError.
func ( interface{},  io.Reader) error {
	var  bytes.Buffer
	 := io.TeeReader(, &)

	 := xml.NewDecoder().Decode()
	if  != nil &&  != io.EOF {
		return awserr.NewUnmarshalError(,
			"failed to unmarshal error message", .Bytes())
	}

	return nil
}
UnmarshalXML deserializes an xml.Decoder into the container v. V needs to match the shape of the XML expected to be decoded. If the shape doesn't match unmarshaling will fail.
func ( interface{},  *xml.Decoder,  string) error {
	,  := XMLToStruct(, nil)
	if  != nil {
		return 
	}
	if .Children != nil {
		for ,  := range .Children {
			for ,  := range  {
				if ,  := .Children[];  {
					 = [0] // pull out wrapped element
				}

				 = parse(reflect.ValueOf(), , "")
				if  != nil {
					if  == io.EOF {
						return nil
					}
					return 
				}
			}
		}
		return nil
	}
	return nil
}
parse deserializes any value from the XMLNode. The type tag is used to infer the type, or reflect will be used to determine the type from r.
func ( reflect.Value,  *XMLNode,  reflect.StructTag) error {
	 := .Get("xml")
	if len() != 0 {
		 := strings.SplitAfterN(, ",", 2)[0]
		if  == "-" {
			return nil
		}
	}

	 := .Type()
	if .Kind() == reflect.Ptr {
		 = .Elem() // check kind of actual element type
	}

	 := .Get("type")
	if  == "" {
		switch .Kind() {
also it can't be a time object
			if ,  := .Interface().(*time.Time); ! {
				 = "structure"
			}
also it can't be a byte slice
			if ,  := .Interface().([]byte); ! {
				 = "list"
			}
		case reflect.Map:
			 = "map"
		}
	}

	switch  {
	case "structure":
		if ,  := .FieldByName("_");  {
			 = .Tag
		}
		return parseStruct(, , )
	case "list":
		return parseList(, , )
	case "map":
		return parseMap(, , )
	default:
		return parseScalar(, , )
	}
}
parseStruct deserializes a structure and its fields from an XMLNode. Any nested types in the structure will also be deserialized.
func ( reflect.Value,  *XMLNode,  reflect.StructTag) error {
	 := .Type()
	if .Kind() == reflect.Ptr {
		if .IsNil() { // create the structure if it's nil
			 := reflect.New(.Type().Elem())
			.Set()
			 = 
		}

		 = .Elem()
		 = .Elem()
	}
unwrap any payloads
	if  := .Get("payload");  != "" {
		,  := .FieldByName()
		return (.FieldByName(), , .Tag)
	}

	for  := 0;  < .NumField(); ++ {
		 := .Field()
		if  := .Name[0:1]; strings.ToLower() ==  {
			continue // ignore unexported fields
		}
figure out what this field is called
		 := .Name
		if .Tag.Get("flattened") != "" && .Tag.Get("locationNameList") != "" {
			 = .Tag.Get("locationNameList")
		} else if  := .Tag.Get("locationName");  != "" {
			 = 
		}
try to find the field by name in elements
		 := .Children[]

		if  == nil { // try to find the field in attributes
			if ,  := .findElem();  {
				 = []*XMLNode{{Text: }}
			}
		}

		 := .FieldByName(.Name)
		for ,  := range  {
			 := parse(, , .Tag)
			if  != nil {
				return 
			}
		}
	}
	return nil
}
parseList deserializes a list of values from an XML node. Each list entry will also be deserialized.
func ( reflect.Value,  *XMLNode,  reflect.StructTag) error {
	 := .Type()

	if .Get("flattened") == "" { // look at all item entries
		 := "member"
		if  := .Get("locationNameList");  != "" {
			 = 
		}

		if ,  := .Children[];  {
			if .IsNil() {
				.Set(reflect.MakeSlice(, len(), len()))
			}

			for ,  := range  {
				 := parse(.Index(), , "")
				if  != nil {
					return 
				}
			}
		}
	} else { // flattened list means this is a single element
		if .IsNil() {
			.Set(reflect.MakeSlice(, 0, 0))
		}

		 := reflect.Zero(.Elem())
		.Set(reflect.Append(, ))
		 := parse(.Index(.Len()-1), , "")
		if  != nil {
			return 
		}
	}

	return nil
}
parseMap deserializes a map from an XMLNode. The direct children of the XMLNode will also be deserialized as map entries.
func ( reflect.Value,  *XMLNode,  reflect.StructTag) error {
	if .IsNil() {
		.Set(reflect.MakeMap(.Type()))
	}

	if .Get("flattened") == "" { // look at all child entries
		for ,  := range .Children["entry"] {
			parseMapEntry(, , )
		}
	} else { // this element is itself an entry
		parseMapEntry(, , )
	}

	return nil
}
parseMapEntry deserializes a map entry from a XML node.
func ( reflect.Value,  *XMLNode,  reflect.StructTag) error {
	,  := "key", "value"
	if  := .Get("locationNameKey");  != "" {
		 = 
	}
	if  := .Get("locationNameValue");  != "" {
		 = 
	}

	,  := .Children[]
	 := .Children[]
	if  {
		for ,  := range  {
			 := reflect.ValueOf(.Text)
			 := []
			 := reflect.New(.Type().Elem()).Elem()

			parse(, , "")
			.SetMapIndex(, )
		}
	}
	return nil
}
parseScaller deserializes an XMLNode value into a concrete type based on the interface type of r. Error is returned if the deserialization fails due to invalid type conversion, or unsupported interface type.
func ( reflect.Value,  *XMLNode,  reflect.StructTag) error {
	switch .Interface().(type) {
	case *string:
		.Set(reflect.ValueOf(&.Text))
		return nil
	case []byte:
		,  := base64.StdEncoding.DecodeString(.Text)
		if  != nil {
			return 
		}
		.Set(reflect.ValueOf())
	case *bool:
		,  := strconv.ParseBool(.Text)
		if  != nil {
			return 
		}
		.Set(reflect.ValueOf(&))
	case *int64:
		,  := strconv.ParseInt(.Text, 10, 64)
		if  != nil {
			return 
		}
		.Set(reflect.ValueOf(&))
	case *float64:
		,  := strconv.ParseFloat(.Text, 64)
		if  != nil {
			return 
		}
		.Set(reflect.ValueOf(&))
	case *time.Time:
		 := .Get("timestampFormat")
		if len() == 0 {
			 = protocol.ISO8601TimeFormatName
		}

		,  := protocol.ParseTime(, .Text)
		if  != nil {
			return 
		}
		.Set(reflect.ValueOf(&))
	default:
		return fmt.Errorf("unsupported value: %v (%s)", .Interface(), .Type())
	}
	return nil