mirror of
https://github.com/golang/go
synced 2024-11-18 11:44:45 -07:00
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>
This commit is contained in:
parent
26c7b4fb1e
commit
2427123d93
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user