diff --git a/src/pkg/encoding/xml/marshal.go b/src/pkg/encoding/xml/marshal.go index 17134c5eb4d..8b2f4173f3a 100644 --- a/src/pkg/encoding/xml/marshal.go +++ b/src/pkg/encoding/xml/marshal.go @@ -273,7 +273,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { s := parentStack{printer: p} for i := range tinfo.fields { finfo := &tinfo.fields[i] - if finfo.flags&(fAttr|fAny) != 0 { + if finfo.flags&(fAttr) != 0 { continue } vf := finfo.value(val) @@ -340,7 +340,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { continue } - case fElement: + case fElement, fElement | fAny: s.trim(finfo.parents) if len(finfo.parents) > len(s.stack) { if vf.Kind() != reflect.Ptr && vf.Kind() != reflect.Interface || !vf.IsNil() { diff --git a/src/pkg/encoding/xml/marshal_test.go b/src/pkg/encoding/xml/marshal_test.go index 668fea6f85e..2ce7721abd1 100644 --- a/src/pkg/encoding/xml/marshal_test.go +++ b/src/pkg/encoding/xml/marshal_test.go @@ -188,6 +188,18 @@ type AnyTest struct { AnyField AnyHolder `xml:",any"` } +type AnyOmitTest struct { + XMLName struct{} `xml:"a"` + Nested string `xml:"nested>value"` + AnyField *AnyHolder `xml:",any,omitempty"` +} + +type AnySliceTest struct { + XMLName struct{} `xml:"a"` + Nested string `xml:"nested>value"` + AnyField []AnyHolder `xml:",any"` +} + type AnyHolder struct { XMLName Name XML string `xml:",innerxml"` @@ -652,12 +664,43 @@ var marshalTests = []struct { XML: "unknown", }, }, - UnmarshalOnly: true, }, { - Value: &AnyTest{Nested: "known", AnyField: AnyHolder{XML: ""}}, - ExpectXML: `known`, - MarshalOnly: true, + Value: &AnyTest{Nested: "known", + AnyField: AnyHolder{ + XML: "", + XMLName: Name{Local: "AnyField"}, + }, + }, + ExpectXML: `known`, + }, + { + ExpectXML: `b`, + Value: &AnyOmitTest{ + Nested: "b", + }, + }, + { + ExpectXML: `bei`, + Value: &AnySliceTest{ + Nested: "b", + AnyField: []AnyHolder{ + { + XMLName: Name{Local: "c"}, + XML: "e", + }, + { + XMLName: Name{Space: "f", Local: "g"}, + XML: "i", + }, + }, + }, + }, + { + ExpectXML: `b`, + Value: &AnySliceTest{ + Nested: "b", + }, }, // Test recursive types. @@ -690,15 +733,17 @@ var marshalTests = []struct { // Test escaping. { - ExpectXML: `dquote: "; squote: '; ampersand: &; less: <; greater: >;`, + ExpectXML: `dquote: "; squote: '; ampersand: &; less: <; greater: >;`, Value: &AnyTest{ - Nested: `dquote: "; squote: '; ampersand: &; less: <; greater: >;`, + Nested: `dquote: "; squote: '; ampersand: &; less: <; greater: >;`, + AnyField: AnyHolder{XMLName: Name{Local: "empty"}}, }, }, { - ExpectXML: `newline: ; cr: ; tab: ;`, + ExpectXML: `newline: ; cr: ; tab: ;`, Value: &AnyTest{ - Nested: "newline: \n; cr: \r; tab: \t;", + Nested: "newline: \n; cr: \r; tab: \t;", + AnyField: AnyHolder{XMLName: Name{Local: "AnyField"}}, }, }, { diff --git a/src/pkg/encoding/xml/read.go b/src/pkg/encoding/xml/read.go index 0e6761d66ad..7a06a29b95a 100644 --- a/src/pkg/encoding/xml/read.go +++ b/src/pkg/encoding/xml/read.go @@ -279,7 +279,7 @@ func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error { saveComment = finfo.value(sv) } - case fAny: + case fAny, fAny | fElement: if !saveAny.IsValid() { saveAny = finfo.value(sv) } diff --git a/src/pkg/encoding/xml/typeinfo.go b/src/pkg/encoding/xml/typeinfo.go index 970d1701932..bbeb28d87ea 100644 --- a/src/pkg/encoding/xml/typeinfo.go +++ b/src/pkg/encoding/xml/typeinfo.go @@ -154,6 +154,9 @@ func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, erro // This will also catch multiple modes in a single field. valid = false } + if finfo.flags&fMode == fAny { + finfo.flags |= fElement + } if finfo.flags&fOmitEmpty != 0 && finfo.flags&(fElement|fAttr) == 0 { valid = false }