| # 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() | |
| // <test:test xmlns:test="urn:example:golang"> | |
| ## 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 |