From 547f1a6fe7915193d6c28dac21648f08e2f67bd9 Mon Sep 17 00:00:00 2001 From: Dmitriy Shelenin Date: Thu, 8 Aug 2013 10:40:51 -0700 Subject: [PATCH] encoding/xml: allow attributes stored in pointers to be marshaled. Fixes #5334. R=golang-dev, dave, rsc CC=golang-dev https://golang.org/cl/8653047 --- src/pkg/encoding/xml/marshal.go | 11 +++++++++- src/pkg/encoding/xml/marshal_test.go | 33 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/pkg/encoding/xml/marshal.go b/src/pkg/encoding/xml/marshal.go index 47b0017634..fae0f6a732 100644 --- a/src/pkg/encoding/xml/marshal.go +++ b/src/pkg/encoding/xml/marshal.go @@ -271,7 +271,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error { continue } fv := finfo.value(val) - if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) { + if (finfo.flags&fOmitEmpty != 0 || fv.Kind() == reflect.Ptr) && isEmptyValue(fv) { continue } p.WriteByte(' ') @@ -285,6 +285,11 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error { } p.WriteString(finfo.name) p.WriteString(`="`) + // Handle pointer values by following the pointer, + // Pointer is known to be non-nil because we called isEmptyValue above. + if fv.Kind() == reflect.Ptr { + fv = fv.Elem() + } if err := p.marshalSimple(fv.Type(), fv); err != nil { return err } @@ -363,6 +368,10 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { continue } vf := finfo.value(val) + // Handle pointer values by following the pointer + if vf.Kind() == reflect.Ptr && !isEmptyValue(vf) { + vf = vf.Elem() + } switch finfo.flags & fMode { case fCharData: var scratch [64]byte diff --git a/src/pkg/encoding/xml/marshal_test.go b/src/pkg/encoding/xml/marshal_test.go index ca14a1e53d..fa2ba52a8f 100644 --- a/src/pkg/encoding/xml/marshal_test.go +++ b/src/pkg/encoding/xml/marshal_test.go @@ -276,6 +276,25 @@ type Strings struct { X []string `xml:"A>B,omitempty"` } +type PointerFieldsTest struct { + XMLName Name `xml:"dummy"` + Name *string `xml:"name,attr"` + Age *uint `xml:"age,attr"` + Empty *string `xml:"empty,attr"` + Contents *string `xml:",chardata"` +} + +type ChardataEmptyTest struct { + XMLName Name `xml:"test"` + Contents *string `xml:",chardata"` +} + +var ( + nameAttr = "Sarah" + ageAttr = uint(12) + contentsAttr = "lorem ipsum" +) + // Unless explicitly stated as such (or *Plain), all of the // tests below are two-way tests. When introducing new tests, // please try to make them two-way as well to ensure that @@ -673,6 +692,20 @@ var marshalTests = []struct { ExpectXML: ``, }, + // pointer fields + { + Value: &PointerFieldsTest{Name: &nameAttr, Age: &ageAttr, Contents: &contentsAttr}, + ExpectXML: `lorem ipsum`, + MarshalOnly: true, + }, + + // empty chardata pointer field + { + Value: &ChardataEmptyTest{}, + ExpectXML: ``, + MarshalOnly: true, + }, + // omitempty on fields { Value: &OmitFieldTest{ -- 2.48.1