Skip to content

Commit 0a464ba

Browse files
SamWhitedianlancetaylor
authored andcommitted
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>
1 parent 4a530da commit 0a464ba

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

design/26756-rawxml-token.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Proposal: Raw XML Token
2+
3+
Author(s): Sam Whited <sam@samwhited.com>
4+
5+
Last updated: 2018-09-01
6+
7+
Discussion at https://golang.org/issue/26756
8+
9+
CL at https://golang.org/cl/127435
10+
11+
12+
## Abstract
13+
14+
This proposal defines a mechanism by which users can emulate the `,innerxml`
15+
struct tag using XML tokens.
16+
17+
18+
## Background
19+
20+
When using the `"*Encoder".EncodeToken` API to write tokens to an XML stream,
21+
it is currently not possible to fully emulate the behavior of `Marshal`.
22+
Specifically, there is no functionality that lets users output XML equivalent to
23+
the `,innerxml` struct tag which inserts raw, unescaped, XML into the output.
24+
For 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+
35+
This cannot be done with the token based output because all token types are
36+
currently escaped.
37+
For example, attempting to output the raw XML as character data results in the
38+
following:
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+
47+
The 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.
53+
type RawXML []byte
54+
55+
// Copy creates a new copy of RawXML.
56+
func (r RawXML) Copy() RawXML { … }
57+
```
58+
59+
60+
## Rationale
61+
62+
When attempting to match the output of legacy XML encoders which may produce
63+
broken escaping, or match the output of XML encoders that support features that
64+
are not currently supported by the [`encoding/xml`] package such as namespace
65+
prefixes it is often desirable to use `,rawxml`.
66+
However, if the user is primarily using the token stream API, it may not be
67+
desirable to switch between encoding tokens and encoding native structures which
68+
is cumbersome and forces a call to `Flush`.
69+
70+
Being able to generate the same output from both the SAX-like and DOM-like APIs
71+
would also allow future proposals the option of fully unifying the two APIs by
72+
creating an encoder equivalent to the `NewTokenDecoder` function.
73+
74+
75+
## Compatibility
76+
77+
This proposal introduces one new exported type that would be covered by the
78+
compatibility promise.
79+
80+
81+
## Implementation
82+
83+
Implementation 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+
90+
None.
91+
92+
93+
[`encoding/xml`]: https://golang.org/pkg/encoding/xml/
94+
[CL 127435]: https://golang.org/cl/127435

0 commit comments

Comments
 (0)