1
0
mirror of https://github.com/golang/go synced 2024-10-05 01:31:22 -06:00

encoding/xml: minor changes

Changes suggested by Nigel Tao in https://go-review.googlesource.com/#/c/11635
after that had been submitted.

Change-Id: I7b28e1c8488c8565399a8017453dc7ff1fd215e8
Reviewed-on: https://go-review.googlesource.com/11832
Reviewed-by: Nigel Tao <nigeltao@golang.org>
This commit is contained in:
Roger Peppe 2015-07-01 09:22:43 +01:00 committed by roger peppe
parent 1cbbd7f545
commit 5ae822ba69

View File

@ -578,9 +578,8 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
// 3. type name // 3. type name
var start StartElement var start StartElement
// explicitNS records whether the element's name // explicitNS records whether the element's name space has been
// space has been explicitly set (for example an // explicitly set (for example an XMLName field).
// and XMLName field).
explicitNS := false explicitNS := false
if startTemplate != nil { if startTemplate != nil {
@ -623,11 +622,11 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
if finfo.flags&fAttr == 0 { if finfo.flags&fAttr == 0 {
continue continue
} }
attr, add, err := p.fieldAttr(finfo, val) attr, err := p.fieldAttr(finfo, val)
if err != nil { if err != nil {
return err return err
} }
if !add { if attr.Name.Local == "" {
continue continue
} }
start.Attr = append(start.Attr, attr) start.Attr = append(start.Attr, attr)
@ -671,62 +670,63 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
return p.cachedWriteError() return p.cachedWriteError()
} }
// fieldAttr returns the attribute of the given field and // fieldAttr returns the attribute of the given field.
// whether it should actually be added as an attribute; // If the returned attribute has an empty Name.Local,
// val holds the value containing the field. // it should not be used.
func (p *printer) fieldAttr(finfo *fieldInfo, val reflect.Value) (Attr, bool, error) { // The given value holds the value containing the field.
func (p *printer) fieldAttr(finfo *fieldInfo, val reflect.Value) (Attr, error) {
fv := finfo.value(val) fv := finfo.value(val)
name := Name{Space: finfo.xmlns, Local: finfo.name} name := Name{Space: finfo.xmlns, Local: finfo.name}
if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) { if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
return Attr{}, false, nil return Attr{}, nil
} }
if fv.Kind() == reflect.Interface && fv.IsNil() { if fv.Kind() == reflect.Interface && fv.IsNil() {
return Attr{}, false, nil return Attr{}, nil
} }
if fv.CanInterface() && fv.Type().Implements(marshalerAttrType) { if fv.CanInterface() && fv.Type().Implements(marshalerAttrType) {
attr, err := fv.Interface().(MarshalerAttr).MarshalXMLAttr(name) attr, err := fv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
return attr, attr.Name.Local != "", err return attr, err
} }
if fv.CanAddr() { if fv.CanAddr() {
pv := fv.Addr() pv := fv.Addr()
if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) { if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) {
attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name) attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
return attr, attr.Name.Local != "", err return attr, err
} }
} }
if fv.CanInterface() && fv.Type().Implements(textMarshalerType) { if fv.CanInterface() && fv.Type().Implements(textMarshalerType) {
text, err := fv.Interface().(encoding.TextMarshaler).MarshalText() text, err := fv.Interface().(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
return Attr{}, false, err return Attr{}, err
} }
return Attr{name, string(text)}, true, nil return Attr{name, string(text)}, nil
} }
if fv.CanAddr() { if fv.CanAddr() {
pv := fv.Addr() pv := fv.Addr()
if pv.CanInterface() && pv.Type().Implements(textMarshalerType) { if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
text, err := pv.Interface().(encoding.TextMarshaler).MarshalText() text, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
if err != nil { if err != nil {
return Attr{}, false, err return Attr{}, err
} }
return Attr{name, string(text)}, true, nil return Attr{name, string(text)}, nil
} }
} }
// Dereference or skip nil pointer, interface values. // Dereference or skip nil pointer, interface values.
switch fv.Kind() { switch fv.Kind() {
case reflect.Ptr, reflect.Interface: case reflect.Ptr, reflect.Interface:
if fv.IsNil() { if fv.IsNil() {
return Attr{}, false, nil return Attr{}, nil
} }
fv = fv.Elem() fv = fv.Elem()
} }
s, b, err := p.marshalSimple(fv.Type(), fv) s, b, err := p.marshalSimple(fv.Type(), fv)
if err != nil { if err != nil {
return Attr{}, false, err return Attr{}, err
} }
if b != nil { if b != nil {
s = string(b) s = string(b)
} }
return Attr{name, s}, true, nil return Attr{name, s}, nil
} }
// defaultStart returns the default start element to use, // defaultStart returns the default start element to use,