diff --git a/src/encoding/xml/marshal.go b/src/encoding/xml/marshal.go
index 133503fa2d..ac3440916a 100644
--- a/src/encoding/xml/marshal.go
+++ b/src/encoding/xml/marshal.go
@@ -580,6 +580,15 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
// marshalAttr marshals an attribute with the given name and value, adding to start.Attr.
func (p *printer) marshalAttr(start *StartElement, name Name, val reflect.Value) error {
+ // Dereference or skip nil pointer, interface values.
+ switch val.Kind() {
+ case reflect.Pointer, reflect.Interface:
+ if val.IsNil() {
+ return nil
+ }
+ val = val.Elem()
+ }
+
if val.CanInterface() && val.Type().Implements(marshalerAttrType) {
attr, err := val.Interface().(MarshalerAttr).MarshalXMLAttr(name)
if err != nil {
@@ -626,15 +635,6 @@ func (p *printer) marshalAttr(start *StartElement, name Name, val reflect.Value)
}
}
- // Dereference or skip nil pointer, interface values.
- switch val.Kind() {
- case reflect.Pointer, reflect.Interface:
- if val.IsNil() {
- return nil
- }
- val = val.Elem()
- }
-
// Walk slices.
if val.Kind() == reflect.Slice && val.Type().Elem().Kind() != reflect.Uint8 {
n := val.Len()
diff --git a/src/encoding/xml/marshal_test.go b/src/encoding/xml/marshal_test.go
index b8bce7170a..c99147ef54 100644
--- a/src/encoding/xml/marshal_test.go
+++ b/src/encoding/xml/marshal_test.go
@@ -343,6 +343,10 @@ type MarshalerStruct struct {
Foo MyMarshalerAttrTest `xml:",attr"`
}
+type IMarshalerStruct struct {
+ Foo interface{} `xml:",attr"`
+}
+
type InnerStruct struct {
XMLName Name `xml:"testns outer"`
}
@@ -1252,6 +1256,11 @@ var marshalTests = []struct {
ExpectXML: ``,
Value: &MarshalerStruct{},
},
+ {
+ ExpectXML: ``,
+ Value: &IMarshalerStruct{Foo: &MyMarshalerAttrTest{}},
+ MarshalOnly: true,
+ },
{
ExpectXML: ``,
Value: &OuterStruct{IntAttr: 10},