design: add raw xml token proposal

See golang/go#26756

Change-Id: I6a2b2fae94d71a784a2489e0af8ca2df4b57bc4c
Reviewed-on: https://go-review.googlesource.com/132836
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/design/26756-rawxml-token.md b/design/26756-rawxml-token.md
new file mode 100644
index 0000000..49e9443
--- /dev/null
+++ b/design/26756-rawxml-token.md
@@ -0,0 +1,94 @@
+# Proposal: Raw XML Token
+
+Author(s): Sam Whited <sam@samwhited.com>
+
+Last updated: 2018-09-01
+
+Discussion at https://golang.org/issue/26756
+
+CL at https://golang.org/cl/127435
+
+
+## Abstract
+
+This proposal defines a mechanism by which users can emulate the `,innerxml`
+struct tag using XML tokens.
+
+
+## Background
+
+When using the `"*Encoder".EncodeToken` API to write tokens to an XML stream,
+it is currently not possible to fully emulate the behavior of `Marshal`.
+Specifically, there is no functionality that lets users output XML equivalent to
+the `,innerxml` struct tag which inserts raw, unescaped, XML into the output.
+For example, consider the following:
+
+    e := xml.NewEncoder(os.Stdout)
+    e.Encode(struct {
+        XMLName xml.Name `xml:"raw"`
+        Inner   string   `xml:",innerxml"`
+        }{
+    Inner: `<test:test xmlns:test="urn:example:golang"/>`,
+    })
+    // Output: <raw><test:test xmlns:test="urn:example:golang"/></raw>
+
+This cannot be done with the token based output because all token types are
+currently escaped.
+For example, attempting to output the raw XML as character data results in the
+following:
+
+    e.EncodeToken(xml.CharData(rawOut))
+    e.Flush()
+    // &lt;test:test xmlns:test=&#34;urn:example:golang&#34;&gt;
+
+
+## Proposal
+
+The proposed API introduces an XML pseudo-token: `RawXML`.
+
+```go
+// RawXML represents some data that should be passed through without escaping.
+// Like a struct field with the ",innerxml" tag, RawXML is written to the
+// stream verbatim and is not subject to the usual escaping rules.
+type RawXML []byte
+
+// Copy creates a new copy of RawXML.
+func (r RawXML) Copy() RawXML { … }
+```
+
+
+## Rationale
+
+When attempting to match the output of legacy XML encoders which may produce
+broken escaping, or match the output of XML encoders that support features that
+are not currently supported by the [`encoding/xml`] package such as namespace
+prefixes it is often desirable to use `,rawxml`.
+However, if the user is primarily using the token stream API, it may not be
+desirable to switch between encoding tokens and encoding native structures which
+is cumbersome and forces a call to `Flush`.
+
+Being able to generate the same output from both the SAX-like and DOM-like APIs
+would also allow future proposals the option of fully unifying the two APIs by
+creating an encoder equivalent to the `NewTokenDecoder` function.
+
+
+## Compatibility
+
+This proposal introduces one new exported type that would be covered by the
+compatibility promise.
+
+
+## Implementation
+
+Implementation of this proposal is trivial, comprising some 5 lines of code
+(excluding tests and comments).
+[CL 127435] has been created to demonstrate the concept.
+
+
+## Open issues
+
+None.
+
+
+[`encoding/xml`]: https://golang.org/pkg/encoding/xml/
+[CL 127435]: https://golang.org/cl/127435