blob: 49e9443d6a76dffd9dacd22261fbfbb601153003 [file] [log] [blame] [view]
Sam Whited0a464ba2018-09-01 14:50:20 -05001# Proposal: Raw XML Token
2
3Author(s): Sam Whited <sam@samwhited.com>
4
5Last updated: 2018-09-01
6
7Discussion at https://golang.org/issue/26756
8
9CL at https://golang.org/cl/127435
10
11
12## Abstract
13
14This proposal defines a mechanism by which users can emulate the `,innerxml`
15struct tag using XML tokens.
16
17
18## Background
19
20When using the `"*Encoder".EncodeToken` API to write tokens to an XML stream,
21it is currently not possible to fully emulate the behavior of `Marshal`.
22Specifically, there is no functionality that lets users output XML equivalent to
23the `,innerxml` struct tag which inserts raw, unescaped, XML into the output.
24For example, consider the following:
25
26 e := xml.NewEncoder(os.Stdout)
27 e.Encode(struct {
28 XMLName xml.Name `xml:"raw"`
29 Inner string `xml:",innerxml"`
30 }{
31 Inner: `<test:test xmlns:test="urn:example:golang"/>`,
32 })
33 // Output: <raw><test:test xmlns:test="urn:example:golang"/></raw>
34
35This cannot be done with the token based output because all token types are
36currently escaped.
37For example, attempting to output the raw XML as character data results in the
38following:
39
40 e.EncodeToken(xml.CharData(rawOut))
41 e.Flush()
42 // &lt;test:test xmlns:test=&#34;urn:example:golang&#34;&gt;
43
44
45## Proposal
46
47The proposed API introduces an XML pseudo-token: `RawXML`.
48
49```go
50// RawXML represents some data that should be passed through without escaping.
51// Like a struct field with the ",innerxml" tag, RawXML is written to the
52// stream verbatim and is not subject to the usual escaping rules.
53type RawXML []byte
54
55// Copy creates a new copy of RawXML.
56func (r RawXML) Copy() RawXML { … }
57```
58
59
60## Rationale
61
62When attempting to match the output of legacy XML encoders which may produce
63broken escaping, or match the output of XML encoders that support features that
64are not currently supported by the [`encoding/xml`] package such as namespace
65prefixes it is often desirable to use `,rawxml`.
66However, if the user is primarily using the token stream API, it may not be
67desirable to switch between encoding tokens and encoding native structures which
68is cumbersome and forces a call to `Flush`.
69
70Being able to generate the same output from both the SAX-like and DOM-like APIs
71would also allow future proposals the option of fully unifying the two APIs by
72creating an encoder equivalent to the `NewTokenDecoder` function.
73
74
75## Compatibility
76
77This proposal introduces one new exported type that would be covered by the
78compatibility promise.
79
80
81## Implementation
82
83Implementation of this proposal is trivial, comprising some 5 lines of code
84(excluding tests and comments).
85[CL 127435] has been created to demonstrate the concept.
86
87
88## Open issues
89
90None.
91
92
93[`encoding/xml`]: https://golang.org/pkg/encoding/xml/
94[CL 127435]: https://golang.org/cl/127435