From 3be158d6ab73090a74df6bc3b7cfa062d896483a Mon Sep 17 00:00:00 2001 From: Roger Peppe Date: Sat, 10 Jan 2015 14:00:21 +0000 Subject: encoding/xml: encoding name spaces correctly The current XML printer does not understand the xmlns attribute. This change changes it so that it interprets the xmlns attributes in the tokens being printed, and uses appropriate prefixes. Fixes #7535. Change-Id: I20fae291d20602d37deb41ed42fab4c9a50ec85d Reviewed-on: https://go-review.googlesource.com/2660 Reviewed-by: Nigel Tao --- src/encoding/xml/xml.go | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'src/encoding/xml/xml.go') diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go index e9535d7b55..0c64cd730d 100644 --- a/src/encoding/xml/xml.go +++ b/src/encoding/xml/xml.go @@ -35,15 +35,24 @@ func (e *SyntaxError) Error() string { return "XML syntax error on line " + strconv.Itoa(e.Line) + ": " + e.Msg } -// A Name represents an XML name (Local) annotated -// with a name space identifier (Space). -// In tokens returned by Decoder.Token, the Space identifier -// is given as a canonical URL, not the short prefix used -// in the document being parsed. +// A Name represents an XML name (Local) annotated with a name space +// identifier (Space). In tokens returned by Decoder.Token, the Space +// identifier is given as a canonical URL, not the short prefix used in +// the document being parsed. +// +// As a special case, XML namespace declarations will use the literal +// string "xmlns" for the Space field instead of the fully resolved URL. +// See Encoder.EncodeToken for more information on namespace encoding +// behaviour. type Name struct { Space, Local string } +// isNamespace reports whether the name is a namespace-defining name. +func (name Name) isNamespace() bool { + return name.Local == "xmlns" || name.Space == "xmlns" +} + // An Attr represents an attribute in an XML element (Name=Value). type Attr struct { Name Name @@ -72,6 +81,24 @@ func (e StartElement) End() EndElement { return EndElement{e.Name} } +// setDefaultNamespace sets the namespace of the element +// as the default for all elements contained within it. +func (e *StartElement) setDefaultNamespace() { + if e.Name.Space == "" { + // If there's no namespace on the element, don't + // set the default. Strictly speaking this might be wrong, as + // we can't tell if the element had no namespace set + // or was just using the default namespace. + return + } + e.Attr = append(e.Attr, Attr{ + Name: Name{ + Local: "xmlns", + }, + Value: e.Name.Space, + }) +} + // An EndElement represents an XML end element. type EndElement struct { Name Name -- cgit v1.3