Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(369)

Unified Diff: src/pkg/encoding/xml/marshal.go

Issue 93320043: encoding/xml: track, use default tag ns in Encoder
Patch Set: diff -r 2fb7165d5fdc https://code.google.com/p/go/ Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/pkg/encoding/xml/marshal_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pkg/encoding/xml/marshal.go
===================================================================
--- a/src/pkg/encoding/xml/marshal.go
+++ b/src/pkg/encoding/xml/marshal.go
@@ -258,6 +258,7 @@
putNewline bool
attrNS map[string]string // map prefix -> name space
attrPrefix map[string]string // map name space -> prefix
+ defaultNS string // current default name space
prefixes []string
tags []Name
}
@@ -322,6 +323,10 @@
// deleteAttrPrefix removes an attribute name space prefix.
func (p *printer) deleteAttrPrefix(prefix string) {
+ if strings.HasPrefix(prefix, "=ns=") {
anacrolix 2014/05/13 23:00:23 Is this some kind of special value?
+ p.defaultNS = prefix[len("=ns="):]
+ return
+ }
delete(p.attrPrefix, p.attrNS[prefix])
delete(p.attrNS, prefix)
}
@@ -341,6 +346,21 @@
}
}
+func (p *printer) pushDefaultNS(ns string) {
+ p.prefixes = append(p.prefixes, "=ns="+ns)
+}
+
+func (p *printer) fieldName(f *fieldInfo) Name {
+ if f.name == "" {
+ return Name{}
+ }
+ space := f.xmlns
+ if f.xmlnsMissing && f.flags&fAttr == 0 {
+ space = p.defaultNS
+ }
+ return Name{space, f.name}
+}
+
var (
marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
marshalerAttrType = reflect.TypeOf((*MarshalerAttr)(nil)).Elem()
@@ -376,23 +396,23 @@
// Check for marshaler.
if val.CanInterface() && typ.Implements(marshalerType) {
- return p.marshalInterface(val.Interface().(Marshaler), defaultStart(typ, finfo, startTemplate))
+ return p.marshalInterface(val.Interface().(Marshaler), p.defaultStart(typ, finfo, startTemplate))
}
if val.CanAddr() {
pv := val.Addr()
if pv.CanInterface() && pv.Type().Implements(marshalerType) {
- return p.marshalInterface(pv.Interface().(Marshaler), defaultStart(pv.Type(), finfo, startTemplate))
+ return p.marshalInterface(pv.Interface().(Marshaler), p.defaultStart(pv.Type(), finfo, startTemplate))
}
}
// Check for text marshaler.
if val.CanInterface() && typ.Implements(textMarshalerType) {
- return p.marshalTextInterface(val.Interface().(encoding.TextMarshaler), defaultStart(typ, finfo, startTemplate))
+ return p.marshalTextInterface(val.Interface().(encoding.TextMarshaler), p.defaultStart(typ, finfo, startTemplate))
}
if val.CanAddr() {
pv := val.Addr()
if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
- return p.marshalTextInterface(pv.Interface().(encoding.TextMarshaler), defaultStart(pv.Type(), finfo, startTemplate))
+ return p.marshalTextInterface(pv.Interface().(encoding.TextMarshaler), p.defaultStart(pv.Type(), finfo, startTemplate))
}
}
@@ -425,19 +445,20 @@
} else if tinfo.xmlname != nil {
xmlname := tinfo.xmlname
if xmlname.name != "" {
- start.Name.Space, start.Name.Local = xmlname.xmlns, xmlname.name
+ start.Name = p.fieldName(xmlname)
} else if v, ok := xmlname.value(val).Interface().(Name); ok && v.Local != "" {
start.Name = v
}
}
if start.Name.Local == "" && finfo != nil {
- start.Name.Space, start.Name.Local = finfo.xmlns, finfo.name
+ start.Name = p.fieldName(finfo)
}
if start.Name.Local == "" {
name := typ.Name()
if name == "" {
return &UnsupportedTypeError{typ}
}
+ start.Name.Space = p.defaultNS
start.Name.Local = name
}
@@ -448,7 +469,7 @@
continue
}
fv := finfo.value(val)
- name := Name{Space: finfo.xmlns, Local: finfo.name}
+ name := p.fieldName(finfo)
if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
continue
@@ -552,7 +573,7 @@
// 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 {
+func (p *printer) defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement {
var start StartElement
// Precedence for the XML element name is as above,
// except that we do not look inside structs for the first field.
@@ -560,13 +581,14 @@
start.Name = startTemplate.Name
start.Attr = append(start.Attr, startTemplate.Attr...)
} else if finfo != nil && finfo.name != "" {
- start.Name.Local = finfo.name
- start.Name.Space = finfo.xmlns
+ start.Name = p.fieldName(finfo)
} else if typ.Name() != "" {
+ start.Name.Space = p.defaultNS
start.Name.Local = typ.Name()
} else {
// Must be a pointer to a named type,
// since it has the Marshaler methods.
+ start.Name.Space = p.defaultNS
start.Name.Local = typ.Elem().Name()
}
return start
@@ -618,8 +640,10 @@
p.WriteByte('<')
p.WriteString(start.Name.Local)
- if start.Name.Space != "" {
+ if start.Name.Space != p.defaultNS {
p.WriteString(` xmlns="`)
+ p.pushDefaultNS(p.defaultNS)
+ p.defaultNS = start.Name.Space
p.EscapeString(start.Name.Space)
p.WriteByte('"')
}
@@ -823,7 +847,7 @@
}
if len(finfo.parents) > len(s.stack) {
if vf.Kind() != reflect.Ptr && vf.Kind() != reflect.Interface || !vf.IsNil() {
- if err := s.push(finfo.parents[len(s.stack):]); err != nil {
+ if err := s.push(p.defaultNS, finfo.parents[len(s.stack):]); err != nil {
return err
}
}
@@ -899,9 +923,9 @@
}
// push adds parent elements to the stack and writes open tags.
-func (s *parentStack) push(parents []string) error {
+func (s *parentStack) push(defaultNS string, parents []string) error {
for i := 0; i < len(parents); i++ {
- if err := s.p.writeStart(&StartElement{Name: Name{Local: parents[i]}}); err != nil {
+ if err := s.p.writeStart(&StartElement{Name: Name{Space: defaultNS, Local: parents[i]}}); err != nil {
return err
}
}
« no previous file with comments | « no previous file | src/pkg/encoding/xml/marshal_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b