func (b *xmlBuilder) buildList(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
	if value.IsNil() {  
		return nil
	}
	flattened := tag.Get("flattened") != ""
	xname := xml.Name{Local: tag.Get("locationName")}
	if flattened {
		for i := 0; i < value.Len(); i++ {
			child := NewXMLElement(xname)
			current.AddChild(child)
			if err := b.buildValue(value.Index(i), child, ""); err != nil {
				return err
			}
		}
	} else {
		list := NewXMLElement(xname)
		current.AddChild(list)
		for i := 0; i < value.Len(); i++ {
			iname := tag.Get("locationNameList")
			if iname == "" {
				iname = "member"
			}
			child := NewXMLElement(xml.Name{Local: iname})
			list.AddChild(child)
			if err := b.buildValue(value.Index(i), child, ""); err != nil {
				return err
			}
		}
	}
	return nil
}
buildList adds the value's list items to the current XMLNode as children nodes. All
nested values in the list are converted to XMLNodes also.
package xmlutil
import (
	"encoding/base64"
	"encoding/xml"
	"fmt"
	"reflect"
	"sort"
	"strconv"
	"strings"
	"time"
)
func BuildXML(params interface{}, e *xml.Encoder) error {
	b := xmlBuilder{encoder: e, namespaces: map[string]string{}}
	root := NewXMLElement(xml.Name{})
	if err := b.buildValue(reflect.ValueOf(params), root, ""); err != nil {
		return err
	}
	for _, c := range root.Children {
		for _, v := range c {
			return StructToXML(e, v, false)
		}
	}
	return nil
}
func elemOf(value reflect.Value) reflect.Value {
	for value.Kind() == reflect.Ptr {
		value = value.Elem()
	}
	return value
}
type xmlBuilder struct {
	encoder    *xml.Encoder
	namespaces map[string]string
}
func (b *xmlBuilder) buildValue(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
	value = elemOf(value)
	if !value.IsValid() {  
		return nil
	} else if tag.Get("location") != "" {  
		return nil
	}
	t := tag.Get("type")
	if t == "" {
		switch value.Kind() {
		case reflect.Struct:
			t = "structure"
		case reflect.Slice:
			t = "list"
		case reflect.Map:
			t = "map"
		}
	}
	switch t {
	case "structure":
		if field, ok := value.Type().FieldByName("SDKShapeTraits"); ok {
			tag = tag + reflect.StructTag(" ") + field.Tag
		}
		return b.buildStruct(value, current, tag)
	case "list":
		return b.buildList(value, current, tag)
	case "map":
		return b.buildMap(value, current, tag)
	default:
		return b.buildScalar(value, current, tag)
	}
}
func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
	if !value.IsValid() {
		return nil
	}
	fieldAdded := false
	if payload := tag.Get("payload"); payload != "" {
		field, _ := value.Type().FieldByName(payload)
		tag = field.Tag
		value = elemOf(value.FieldByName(payload))
		if !value.IsValid() {
			return nil
		}
	}
	child := NewXMLElement(xml.Name{Local: tag.Get("locationName")})
	if prefix, uri := tag.Get("xmlPrefix"), tag.Get("xmlURI"); uri != "" {
		ns := xml.Attr{
			Name:  xml.Name{Local: "xmlns"},
			Value: uri,
		}
		if prefix != "" {
			b.namespaces[prefix] = uri  
			ns.Name.Local = "xmlns:" + prefix
		}
		child.Attr = append(child.Attr, ns)
	}
	t := value.Type()
	for i := 0; i < value.NumField(); i++ {
		if c := t.Field(i).Name[0:1]; strings.ToLower(c) == c {
			continue  
		}
		member := elemOf(value.Field(i))
		field := t.Field(i)
		mTag := field.Tag
		if mTag.Get("location") != "" {  
			continue
		}
		memberName := mTag.Get("locationName")
		if memberName == "" {
			memberName = field.Name
			mTag = reflect.StructTag(string(mTag) + ` locationName:"` + memberName + `"`)
		}
		if err := b.buildValue(member, child, mTag); err != nil {
			return err
		}
		fieldAdded = true
	}
	if fieldAdded {  
		current.AddChild(child)
	}
	return nil
}