aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/xml
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2016-10-12 22:42:40 -0400
committerRuss Cox <rsc@golang.org>2016-10-13 17:47:44 +0000
commit2427123d9391134a68c6f60b5acbcb6f60856ff8 (patch)
treebf44a8af7bd11f0c56250c654cac1be1841c8cbf /src/encoding/xml
parent26c7b4fb1e0553e8f9abe5fdd9008bb1f5bd3228 (diff)
downloadgo-2427123d9391134a68c6f60b5acbcb6f60856ff8.tar.gz
go-2427123d9391134a68c6f60b5acbcb6f60856ff8.zip
encoding/xml: split attribute marshaling into its own method
No functional changes here. Just makes next CL easier to read. Change-Id: Icf7b2281b4da6cb59ff4edff05943b2ee288576a Reviewed-on: https://go-review.googlesource.com/30945 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/encoding/xml')
-rw-r--r--src/encoding/xml/marshal.go132
1 files changed, 70 insertions, 62 deletions
diff --git a/src/encoding/xml/marshal.go b/src/encoding/xml/marshal.go
index 4fa1de040a..7f22cdad44 100644
--- a/src/encoding/xml/marshal.go
+++ b/src/encoding/xml/marshal.go
@@ -494,7 +494,6 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
continue
}
fv := finfo.value(val)
- name := Name{Space: finfo.xmlns, Local: finfo.name}
if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
continue
@@ -504,69 +503,10 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
continue
}
- if fv.CanInterface() && fv.Type().Implements(marshalerAttrType) {
- attr, err := fv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
- if err != nil {
- return err
- }
- if attr.Name.Local != "" {
- start.Attr = append(start.Attr, attr)
- }
- continue
- }
-
- if fv.CanAddr() {
- pv := fv.Addr()
- if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) {
- attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
- if err != nil {
- return err
- }
- if attr.Name.Local != "" {
- start.Attr = append(start.Attr, attr)
- }
- continue
- }
- }
-
- if fv.CanInterface() && fv.Type().Implements(textMarshalerType) {
- text, err := fv.Interface().(encoding.TextMarshaler).MarshalText()
- if err != nil {
- return err
- }
- start.Attr = append(start.Attr, Attr{name, string(text)})
- continue
- }
-
- if fv.CanAddr() {
- pv := fv.Addr()
- if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
- text, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
- if err != nil {
- return err
- }
- start.Attr = append(start.Attr, Attr{name, string(text)})
- continue
- }
- }
-
- // Dereference or skip nil pointer, interface values.
- switch fv.Kind() {
- case reflect.Ptr, reflect.Interface:
- if fv.IsNil() {
- continue
- }
- fv = fv.Elem()
- }
-
- s, b, err := p.marshalSimple(fv.Type(), fv)
- if err != nil {
+ name := Name{Space: finfo.xmlns, Local: finfo.name}
+ if err := p.marshalAttr(&start, name, fv); err != nil {
return err
}
- if b != nil {
- s = string(b)
- }
- start.Attr = append(start.Attr, Attr{name, s})
}
if err := p.writeStart(&start); err != nil {
@@ -596,6 +536,74 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
return p.cachedWriteError()
}
+// 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 {
+ if val.CanInterface() && val.Type().Implements(marshalerAttrType) {
+ attr, err := val.Interface().(MarshalerAttr).MarshalXMLAttr(name)
+ if err != nil {
+ return err
+ }
+ if attr.Name.Local != "" {
+ start.Attr = append(start.Attr, attr)
+ }
+ return nil
+ }
+
+ if val.CanAddr() {
+ pv := val.Addr()
+ if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) {
+ attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
+ if err != nil {
+ return err
+ }
+ if attr.Name.Local != "" {
+ start.Attr = append(start.Attr, attr)
+ }
+ return nil
+ }
+ }
+
+ if val.CanInterface() && val.Type().Implements(textMarshalerType) {
+ text, err := val.Interface().(encoding.TextMarshaler).MarshalText()
+ if err != nil {
+ return err
+ }
+ start.Attr = append(start.Attr, Attr{name, string(text)})
+ return nil
+ }
+
+ if val.CanAddr() {
+ pv := val.Addr()
+ if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
+ text, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
+ if err != nil {
+ return err
+ }
+ start.Attr = append(start.Attr, Attr{name, string(text)})
+ return nil
+ }
+ }
+
+ // Dereference or skip nil pointer, interface values.
+ switch val.Kind() {
+ case reflect.Ptr, reflect.Interface:
+ if val.IsNil() {
+ return nil
+ }
+ val = val.Elem()
+ }
+
+ s, b, err := p.marshalSimple(val.Type(), val)
+ if err != nil {
+ return err
+ }
+ if b != nil {
+ s = string(b)
+ }
+ start.Attr = append(start.Attr, Attr{name, s})
+ return nil
+}
+
// defaultStart returns the default start element to use,
// given the reflect type, field info, and start template.
func defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement {