mirror of
https://github.com/golang/go
synced 2024-11-18 14:44:41 -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
|
continue
|
||||||
}
|
}
|
||||||
fv := finfo.value(val)
|
fv := finfo.value(val)
|
||||||
name := Name{Space: finfo.xmlns, Local: finfo.name}
|
|
||||||
|
|
||||||
if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
|
if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
|
||||||
continue
|
continue
|
||||||
@ -504,69 +503,10 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if fv.CanInterface() && fv.Type().Implements(marshalerAttrType) {
|
name := Name{Space: finfo.xmlns, Local: finfo.name}
|
||||||
attr, err := fv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
|
if err := p.marshalAttr(&start, name, fv); err != nil {
|
||||||
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 {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if b != nil {
|
|
||||||
s = string(b)
|
|
||||||
}
|
|
||||||
start.Attr = append(start.Attr, Attr{name, s})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.writeStart(&start); err != nil {
|
if err := p.writeStart(&start); err != nil {
|
||||||
@ -596,6 +536,74 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
|
|||||||
return p.cachedWriteError()
|
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,
|
// defaultStart returns the default start element to use,
|
||||||
// given the reflect type, field info, and start template.
|
// given the reflect type, field info, and start template.
|
||||||
func defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement {
|
func defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement {
|
||||||
|
Loading…
Reference in New Issue
Block a user