diff --git a/src/encoding/xml/marshal.go b/src/encoding/xml/marshal.go
index 1176f5d717d0b47692d84f511570fcf09045985e..4c6ba8c1a5abee01f1be377661fbb588ef5438a1 100644
--- a/src/encoding/xml/marshal.go
+++ b/src/encoding/xml/marshal.go
@@ -775,6 +775,20 @@ func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []
 
 var ddBytes = []byte("--")
 
+// indirect drills into interfaces and pointers, returning the pointed-at value.
+// If it encounters a nil interface or pointer, indirect returns that nil value.
+// This can turn into an infinite loop given a cyclic chain,
+// but it matches the Go 1 behavior.
+func indirect(vf reflect.Value) reflect.Value {
+	for vf.Kind() == reflect.Interface || vf.Kind() == reflect.Ptr {
+		if vf.IsNil() {
+			return vf
+		}
+		vf = vf.Elem()
+	}
+	return vf
+}
+
 func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
 	s := parentStack{p: p}
 	for i := range tinfo.fields {
@@ -816,17 +830,9 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
 					continue
 				}
 			}
-			// Drill into interfaces and pointers.
-			// This can turn into an infinite loop given a cyclic chain,
-			// but it matches the Go 1 behavior.
-			for vf.Kind() == reflect.Interface || vf.Kind() == reflect.Ptr {
-				if vf.IsNil() {
-					return nil
-				}
-				vf = vf.Elem()
-			}
 
 			var scratch [64]byte
+			vf = indirect(vf)
 			switch vf.Kind() {
 			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 				if err := emit(p, strconv.AppendInt(scratch[:0], vf.Int(), 10)); err != nil {
@@ -861,6 +867,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
 			if err := s.trim(finfo.parents); err != nil {
 				return err
 			}
+			vf = indirect(vf)
 			k := vf.Kind()
 			if !(k == reflect.String || k == reflect.Slice && vf.Type().Elem().Kind() == reflect.Uint8) {
 				return fmt.Errorf("xml: bad type for comment field of %s", val.Type())
@@ -901,6 +908,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
 			continue
 
 		case fInnerXml:
+			vf = indirect(vf)
 			iface := vf.Interface()
 			switch raw := iface.(type) {
 			case []byte:
diff --git a/src/encoding/xml/marshal_test.go b/src/encoding/xml/marshal_test.go
index d79b99a1e0b7264eaebe05c0fdd439090c5355f1..5ec7ececa4d039331bfec347269bccf2e2b71e31 100644
--- a/src/encoding/xml/marshal_test.go
+++ b/src/encoding/xml/marshal_test.go
@@ -386,6 +386,140 @@ func ifaceptr(x interface{}) interface{} {
 	return &x
 }
 
+func stringptr(x string) *string {
+	return &x
+}
+
+type T1 struct{}
+type T2 struct{}
+type T3 struct{}
+
+type IndirComment struct {
+	T1      T1
+	Comment *string `xml:",comment"`
+	T2      T2
+}
+
+type DirectComment struct {
+	T1      T1
+	Comment string `xml:",comment"`
+	T2      T2
+}
+
+type IfaceComment struct {
+	T1      T1
+	Comment interface{} `xml:",comment"`
+	T2      T2
+}
+
+type IndirChardata struct {
+	T1       T1
+	Chardata *string `xml:",chardata"`
+	T2       T2
+}
+
+type DirectChardata struct {
+	T1       T1
+	Chardata string `xml:",chardata"`
+	T2       T2
+}
+
+type IfaceChardata struct {
+	T1       T1
+	Chardata interface{} `xml:",chardata"`
+	T2       T2
+}
+
+type IndirCDATA struct {
+	T1    T1
+	CDATA *string `xml:",cdata"`
+	T2    T2
+}
+
+type DirectCDATA struct {
+	T1    T1
+	CDATA string `xml:",cdata"`
+	T2    T2
+}
+
+type IfaceCDATA struct {
+	T1    T1
+	CDATA interface{} `xml:",cdata"`
+	T2    T2
+}
+
+type IndirInnerXML struct {
+	T1       T1
+	InnerXML *string `xml:",innerxml"`
+	T2       T2
+}
+
+type DirectInnerXML struct {
+	T1       T1
+	InnerXML string `xml:",innerxml"`
+	T2       T2
+}
+
+type IfaceInnerXML struct {
+	T1       T1
+	InnerXML interface{} `xml:",innerxml"`
+	T2       T2
+}
+
+type IndirElement struct {
+	T1      T1
+	Element *string
+	T2      T2
+}
+
+type DirectElement struct {
+	T1      T1
+	Element string
+	T2      T2
+}
+
+type IfaceElement struct {
+	T1      T1
+	Element interface{}
+	T2      T2
+}
+
+type IndirOmitEmpty struct {
+	T1        T1
+	OmitEmpty *string `xml:",omitempty"`
+	T2        T2
+}
+
+type DirectOmitEmpty struct {
+	T1        T1
+	OmitEmpty string `xml:",omitempty"`
+	T2        T2
+}
+
+type IfaceOmitEmpty struct {
+	T1        T1
+	OmitEmpty interface{} `xml:",omitempty"`
+	T2        T2
+}
+
+type IndirAny struct {
+	T1  T1
+	Any *string `xml:",any"`
+	T2  T2
+}
+
+type DirectAny struct {
+	T1  T1
+	Any string `xml:",any"`
+	T2  T2
+}
+
+type IfaceAny struct {
+	T1  T1
+	Any interface{} `xml:",any"`
+	T2  T2
+}
+
 var (
 	nameAttr     = "Sarah"
 	ageAttr      = uint(12)
@@ -398,10 +532,12 @@ var (
 // please try to make them two-way as well to ensure that
 // marshaling and unmarshaling are as symmetrical as feasible.
 var marshalTests = []struct {
-	Value         interface{}
-	ExpectXML     string
-	MarshalOnly   bool
-	UnmarshalOnly bool
+	Value          interface{}
+	ExpectXML      string
+	MarshalOnly    bool
+	MarshalError   string
+	UnmarshalOnly  bool
+	UnmarshalError string
 }{
 	// Test nil marshals to nothing
 	{Value: nil, ExpectXML: ``, MarshalOnly: true},
@@ -1133,6 +1269,382 @@ var marshalTests = []struct {
 		ExpectXML: `<NestedAndCData><A><B></B><B></B></A><![CDATA[test]]></NestedAndCData>`,
 		Value:     &NestedAndCData{AB: make([]string, 2), CDATA: "test"},
 	},
+	// Test pointer indirection in various kinds of fields.
+	// https://golang.org/issue/19063
+	{
+		ExpectXML:   `<IndirComment><T1></T1><!--hi--><T2></T2></IndirComment>`,
+		Value:       &IndirComment{Comment: stringptr("hi")},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML:   `<IndirComment><T1></T1><T2></T2></IndirComment>`,
+		Value:       &IndirComment{Comment: stringptr("")},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML:    `<IndirComment><T1></T1><T2></T2></IndirComment>`,
+		Value:        &IndirComment{Comment: nil},
+		MarshalError: "xml: bad type for comment field of xml.IndirComment",
+	},
+	{
+		ExpectXML:     `<IndirComment><T1></T1><!--hi--><T2></T2></IndirComment>`,
+		Value:         &IndirComment{Comment: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:   `<IfaceComment><T1></T1><!--hi--><T2></T2></IfaceComment>`,
+		Value:       &IfaceComment{Comment: "hi"},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<IfaceComment><T1></T1><!--hi--><T2></T2></IfaceComment>`,
+		Value:         &IfaceComment{Comment: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:    `<IfaceComment><T1></T1><T2></T2></IfaceComment>`,
+		Value:        &IfaceComment{Comment: nil},
+		MarshalError: "xml: bad type for comment field of xml.IfaceComment",
+	},
+	{
+		ExpectXML:     `<IfaceComment><T1></T1><T2></T2></IfaceComment>`,
+		Value:         &IfaceComment{Comment: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML: `<DirectComment><T1></T1><!--hi--><T2></T2></DirectComment>`,
+		Value:     &DirectComment{Comment: string("hi")},
+	},
+	{
+		ExpectXML: `<DirectComment><T1></T1><T2></T2></DirectComment>`,
+		Value:     &DirectComment{Comment: string("")},
+	},
+	{
+		ExpectXML: `<IndirChardata><T1></T1>hi<T2></T2></IndirChardata>`,
+		Value:     &IndirChardata{Chardata: stringptr("hi")},
+	},
+	{
+		ExpectXML:     `<IndirChardata><T1></T1><![CDATA[hi]]><T2></T2></IndirChardata>`,
+		Value:         &IndirChardata{Chardata: stringptr("hi")},
+		UnmarshalOnly: true, // marshals without CDATA
+	},
+	{
+		ExpectXML: `<IndirChardata><T1></T1><T2></T2></IndirChardata>`,
+		Value:     &IndirChardata{Chardata: stringptr("")},
+	},
+	{
+		ExpectXML:   `<IndirChardata><T1></T1><T2></T2></IndirChardata>`,
+		Value:       &IndirChardata{Chardata: nil},
+		MarshalOnly: true, // unmarshal leaves Chardata=stringptr("")
+	},
+	{
+		ExpectXML:      `<IfaceChardata><T1></T1>hi<T2></T2></IfaceChardata>`,
+		Value:          &IfaceChardata{Chardata: string("hi")},
+		UnmarshalError: "cannot unmarshal into interface {}",
+	},
+	{
+		ExpectXML:      `<IfaceChardata><T1></T1><![CDATA[hi]]><T2></T2></IfaceChardata>`,
+		Value:          &IfaceChardata{Chardata: string("hi")},
+		UnmarshalOnly:  true, // marshals without CDATA
+		UnmarshalError: "cannot unmarshal into interface {}",
+	},
+	{
+		ExpectXML:      `<IfaceChardata><T1></T1><T2></T2></IfaceChardata>`,
+		Value:          &IfaceChardata{Chardata: string("")},
+		UnmarshalError: "cannot unmarshal into interface {}",
+	},
+	{
+		ExpectXML:      `<IfaceChardata><T1></T1><T2></T2></IfaceChardata>`,
+		Value:          &IfaceChardata{Chardata: nil},
+		UnmarshalError: "cannot unmarshal into interface {}",
+	},
+	{
+		ExpectXML: `<DirectChardata><T1></T1>hi<T2></T2></DirectChardata>`,
+		Value:     &DirectChardata{Chardata: string("hi")},
+	},
+	{
+		ExpectXML:     `<DirectChardata><T1></T1><![CDATA[hi]]><T2></T2></DirectChardata>`,
+		Value:         &DirectChardata{Chardata: string("hi")},
+		UnmarshalOnly: true, // marshals without CDATA
+	},
+	{
+		ExpectXML: `<DirectChardata><T1></T1><T2></T2></DirectChardata>`,
+		Value:     &DirectChardata{Chardata: string("")},
+	},
+	{
+		ExpectXML: `<IndirCDATA><T1></T1><![CDATA[hi]]><T2></T2></IndirCDATA>`,
+		Value:     &IndirCDATA{CDATA: stringptr("hi")},
+	},
+	{
+		ExpectXML:     `<IndirCDATA><T1></T1>hi<T2></T2></IndirCDATA>`,
+		Value:         &IndirCDATA{CDATA: stringptr("hi")},
+		UnmarshalOnly: true, // marshals with CDATA
+	},
+	{
+		ExpectXML: `<IndirCDATA><T1></T1><T2></T2></IndirCDATA>`,
+		Value:     &IndirCDATA{CDATA: stringptr("")},
+	},
+	{
+		ExpectXML:   `<IndirCDATA><T1></T1><T2></T2></IndirCDATA>`,
+		Value:       &IndirCDATA{CDATA: nil},
+		MarshalOnly: true, // unmarshal leaves CDATA=stringptr("")
+	},
+	{
+		ExpectXML:      `<IfaceCDATA><T1></T1><![CDATA[hi]]><T2></T2></IfaceCDATA>`,
+		Value:          &IfaceCDATA{CDATA: string("hi")},
+		UnmarshalError: "cannot unmarshal into interface {}",
+	},
+	{
+		ExpectXML:      `<IfaceCDATA><T1></T1>hi<T2></T2></IfaceCDATA>`,
+		Value:          &IfaceCDATA{CDATA: string("hi")},
+		UnmarshalOnly:  true, // marshals with CDATA
+		UnmarshalError: "cannot unmarshal into interface {}",
+	},
+	{
+		ExpectXML:      `<IfaceCDATA><T1></T1><T2></T2></IfaceCDATA>`,
+		Value:          &IfaceCDATA{CDATA: string("")},
+		UnmarshalError: "cannot unmarshal into interface {}",
+	},
+	{
+		ExpectXML:      `<IfaceCDATA><T1></T1><T2></T2></IfaceCDATA>`,
+		Value:          &IfaceCDATA{CDATA: nil},
+		UnmarshalError: "cannot unmarshal into interface {}",
+	},
+	{
+		ExpectXML: `<DirectCDATA><T1></T1><![CDATA[hi]]><T2></T2></DirectCDATA>`,
+		Value:     &DirectCDATA{CDATA: string("hi")},
+	},
+	{
+		ExpectXML:     `<DirectCDATA><T1></T1>hi<T2></T2></DirectCDATA>`,
+		Value:         &DirectCDATA{CDATA: string("hi")},
+		UnmarshalOnly: true, // marshals with CDATA
+	},
+	{
+		ExpectXML: `<DirectCDATA><T1></T1><T2></T2></DirectCDATA>`,
+		Value:     &DirectCDATA{CDATA: string("")},
+	},
+	{
+		ExpectXML:   `<IndirInnerXML><T1></T1><hi/><T2></T2></IndirInnerXML>`,
+		Value:       &IndirInnerXML{InnerXML: stringptr("<hi/>")},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML:   `<IndirInnerXML><T1></T1><T2></T2></IndirInnerXML>`,
+		Value:       &IndirInnerXML{InnerXML: stringptr("")},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML: `<IndirInnerXML><T1></T1><T2></T2></IndirInnerXML>`,
+		Value:     &IndirInnerXML{InnerXML: nil},
+	},
+	{
+		ExpectXML:     `<IndirInnerXML><T1></T1><hi/><T2></T2></IndirInnerXML>`,
+		Value:         &IndirInnerXML{InnerXML: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:   `<IfaceInnerXML><T1></T1><hi/><T2></T2></IfaceInnerXML>`,
+		Value:       &IfaceInnerXML{InnerXML: "<hi/>"},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<IfaceInnerXML><T1></T1><hi/><T2></T2></IfaceInnerXML>`,
+		Value:         &IfaceInnerXML{InnerXML: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML: `<IfaceInnerXML><T1></T1><T2></T2></IfaceInnerXML>`,
+		Value:     &IfaceInnerXML{InnerXML: nil},
+	},
+	{
+		ExpectXML:     `<IfaceInnerXML><T1></T1><T2></T2></IfaceInnerXML>`,
+		Value:         &IfaceInnerXML{InnerXML: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:   `<DirectInnerXML><T1></T1><hi/><T2></T2></DirectInnerXML>`,
+		Value:       &DirectInnerXML{InnerXML: string("<hi/>")},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<DirectInnerXML><T1></T1><hi/><T2></T2></DirectInnerXML>`,
+		Value:         &DirectInnerXML{InnerXML: string("<T1></T1><hi/><T2></T2>")},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:   `<DirectInnerXML><T1></T1><T2></T2></DirectInnerXML>`,
+		Value:       &DirectInnerXML{InnerXML: string("")},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<DirectInnerXML><T1></T1><T2></T2></DirectInnerXML>`,
+		Value:         &DirectInnerXML{InnerXML: string("<T1></T1><T2></T2>")},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML: `<IndirElement><T1></T1><Element>hi</Element><T2></T2></IndirElement>`,
+		Value:     &IndirElement{Element: stringptr("hi")},
+	},
+	{
+		ExpectXML: `<IndirElement><T1></T1><Element></Element><T2></T2></IndirElement>`,
+		Value:     &IndirElement{Element: stringptr("")},
+	},
+	{
+		ExpectXML: `<IndirElement><T1></T1><T2></T2></IndirElement>`,
+		Value:     &IndirElement{Element: nil},
+	},
+	{
+		ExpectXML:   `<IfaceElement><T1></T1><Element>hi</Element><T2></T2></IfaceElement>`,
+		Value:       &IfaceElement{Element: "hi"},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<IfaceElement><T1></T1><Element>hi</Element><T2></T2></IfaceElement>`,
+		Value:         &IfaceElement{Element: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML: `<IfaceElement><T1></T1><T2></T2></IfaceElement>`,
+		Value:     &IfaceElement{Element: nil},
+	},
+	{
+		ExpectXML:     `<IfaceElement><T1></T1><T2></T2></IfaceElement>`,
+		Value:         &IfaceElement{Element: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML: `<DirectElement><T1></T1><Element>hi</Element><T2></T2></DirectElement>`,
+		Value:     &DirectElement{Element: string("hi")},
+	},
+	{
+		ExpectXML: `<DirectElement><T1></T1><Element></Element><T2></T2></DirectElement>`,
+		Value:     &DirectElement{Element: string("")},
+	},
+	{
+		ExpectXML: `<IndirOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IndirOmitEmpty>`,
+		Value:     &IndirOmitEmpty{OmitEmpty: stringptr("hi")},
+	},
+	{
+		// Note: Changed in Go 1.8 to include <OmitEmpty> element (because x.OmitEmpty != nil).
+		ExpectXML:   `<IndirOmitEmpty><T1></T1><OmitEmpty></OmitEmpty><T2></T2></IndirOmitEmpty>`,
+		Value:       &IndirOmitEmpty{OmitEmpty: stringptr("")},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<IndirOmitEmpty><T1></T1><OmitEmpty></OmitEmpty><T2></T2></IndirOmitEmpty>`,
+		Value:         &IndirOmitEmpty{OmitEmpty: stringptr("")},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML: `<IndirOmitEmpty><T1></T1><T2></T2></IndirOmitEmpty>`,
+		Value:     &IndirOmitEmpty{OmitEmpty: nil},
+	},
+	{
+		ExpectXML:   `<IfaceOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IfaceOmitEmpty>`,
+		Value:       &IfaceOmitEmpty{OmitEmpty: "hi"},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<IfaceOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IfaceOmitEmpty>`,
+		Value:         &IfaceOmitEmpty{OmitEmpty: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML: `<IfaceOmitEmpty><T1></T1><T2></T2></IfaceOmitEmpty>`,
+		Value:     &IfaceOmitEmpty{OmitEmpty: nil},
+	},
+	{
+		ExpectXML:     `<IfaceOmitEmpty><T1></T1><T2></T2></IfaceOmitEmpty>`,
+		Value:         &IfaceOmitEmpty{OmitEmpty: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML: `<DirectOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></DirectOmitEmpty>`,
+		Value:     &DirectOmitEmpty{OmitEmpty: string("hi")},
+	},
+	{
+		ExpectXML: `<DirectOmitEmpty><T1></T1><T2></T2></DirectOmitEmpty>`,
+		Value:     &DirectOmitEmpty{OmitEmpty: string("")},
+	},
+	{
+		ExpectXML: `<IndirAny><T1></T1><Any>hi</Any><T2></T2></IndirAny>`,
+		Value:     &IndirAny{Any: stringptr("hi")},
+	},
+	{
+		ExpectXML: `<IndirAny><T1></T1><Any></Any><T2></T2></IndirAny>`,
+		Value:     &IndirAny{Any: stringptr("")},
+	},
+	{
+		ExpectXML: `<IndirAny><T1></T1><T2></T2></IndirAny>`,
+		Value:     &IndirAny{Any: nil},
+	},
+	{
+		ExpectXML:   `<IfaceAny><T1></T1><Any>hi</Any><T2></T2></IfaceAny>`,
+		Value:       &IfaceAny{Any: "hi"},
+		MarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<IfaceAny><T1></T1><Any>hi</Any><T2></T2></IfaceAny>`,
+		Value:         &IfaceAny{Any: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML: `<IfaceAny><T1></T1><T2></T2></IfaceAny>`,
+		Value:     &IfaceAny{Any: nil},
+	},
+	{
+		ExpectXML:     `<IfaceAny><T1></T1><T2></T2></IfaceAny>`,
+		Value:         &IfaceAny{Any: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML: `<DirectAny><T1></T1><Any>hi</Any><T2></T2></DirectAny>`,
+		Value:     &DirectAny{Any: string("hi")},
+	},
+	{
+		ExpectXML: `<DirectAny><T1></T1><Any></Any><T2></T2></DirectAny>`,
+		Value:     &DirectAny{Any: string("")},
+	},
+	{
+		ExpectXML:     `<IndirFoo><T1></T1><Foo>hi</Foo><T2></T2></IndirFoo>`,
+		Value:         &IndirAny{Any: stringptr("hi")},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<IndirFoo><T1></T1><Foo></Foo><T2></T2></IndirFoo>`,
+		Value:         &IndirAny{Any: stringptr("")},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<IndirFoo><T1></T1><T2></T2></IndirFoo>`,
+		Value:         &IndirAny{Any: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<IfaceFoo><T1></T1><Foo>hi</Foo><T2></T2></IfaceFoo>`,
+		Value:         &IfaceAny{Any: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<IfaceFoo><T1></T1><T2></T2></IfaceFoo>`,
+		Value:         &IfaceAny{Any: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<IfaceFoo><T1></T1><T2></T2></IfaceFoo>`,
+		Value:         &IfaceAny{Any: nil},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<DirectFoo><T1></T1><Foo>hi</Foo><T2></T2></DirectFoo>`,
+		Value:         &DirectAny{Any: string("hi")},
+		UnmarshalOnly: true,
+	},
+	{
+		ExpectXML:     `<DirectFoo><T1></T1><Foo></Foo><T2></T2></DirectFoo>`,
+		Value:         &DirectAny{Any: string("")},
+		UnmarshalOnly: true,
+	},
 }
 
 func TestMarshal(t *testing.T) {
@@ -1142,7 +1654,17 @@ func TestMarshal(t *testing.T) {
 		}
 		data, err := Marshal(test.Value)
 		if err != nil {
-			t.Errorf("#%d: marshal(%#v): %s", idx, test.Value, err)
+			if test.MarshalError == "" {
+				t.Errorf("#%d: marshal(%#v): %s", idx, test.Value, err)
+				continue
+			}
+			if !strings.Contains(err.Error(), test.MarshalError) {
+				t.Errorf("#%d: marshal(%#v): %s, want %q", idx, test.Value, err, test.MarshalError)
+			}
+			continue
+		}
+		if test.MarshalError != "" {
+			t.Errorf("#%d: Marshal succeeded, want error %q", idx, test.MarshalError)
 			continue
 		}
 		if got, want := string(data), test.ExpectXML; got != want {
@@ -1268,8 +1790,16 @@ func TestUnmarshal(t *testing.T) {
 		}
 
 		if err != nil {
-			t.Errorf("#%d: unexpected error: %#v", i, err)
-		} else if got, want := dest, test.Value; !reflect.DeepEqual(got, want) {
+			if test.UnmarshalError == "" {
+				t.Errorf("#%d: unmarshal(%#v): %s", i, test.ExpectXML, err)
+				continue
+			}
+			if !strings.Contains(err.Error(), test.UnmarshalError) {
+				t.Errorf("#%d: unmarshal(%#v): %s, want %q", i, test.ExpectXML, err, test.UnmarshalError)
+			}
+			continue
+		}
+		if got, want := dest, test.Value; !reflect.DeepEqual(got, want) {
 			t.Errorf("#%d: unmarshal(%q):\nhave %#v\nwant %#v", i, test.ExpectXML, got, want)
 		}
 	}