1313@interaction-eval[#:eval xml-eval (require xml)]
1414@interaction-eval[#:eval xml-eval (require racket/list)]
1515@interaction-eval[#:eval plist-eval (require xml/plist)]
16+ @(define reference '(lib "scribblings/reference/reference.scrbl " ))
1617
1718@title{XML: Parsing and Writing}
1819
@@ -38,7 +39,13 @@ It does not interpret namespaces either.
3839 [char (or/c #f exact-nonnegative-integer?)]
3940 [offset exact-nonnegative-integer?])]{
4041
41- Represents a location in an input stream. The offset is a character offset unless @racket[xml-count-bytes] is @racket[#t ], in which case it is a byte offset.}
42+ Represents a location in an input stream. The offset is a
43+ character offset unless @racket[xml-count-bytes] is
44+ @racket[#t ], in which case it is a byte offset.
45+
46+ @history[
47+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
48+ ]}
4249
4350@defthing[location/c contract?]{
4451 Equivalent to @racket[(or/c location? symbol? #f )].
@@ -53,30 +60,83 @@ Represents a source location. Other structure types extend
5360When XML is generated from an input stream by @racket[read-xml],
5461locations are represented by @racket[location] instances. When XML
5562structures are generated by @racket[xexpr->xml], then locations are
56- symbols.}
63+ symbols.
64+
65+ @margin-note{Immediate instances of @racket[source] are not
66+ @tech[#:doc reference]{serializable}. The @racketmodname[xml] library
67+ only uses @tech[#:doc reference #:key "structure subtypes " ]{subtypes}
68+ of @racket[source].}
69+ }
5770
5871@deftogether[(
5972@defstruct[external-dtd ([system string?])]
6073@defstruct[(external-dtd/public external-dtd) ([public string?])]
6174@defstruct[(external-dtd/system external-dtd) ()]
75+ @defthing[no-external-dtd external-dtd? #:value (external-dtd "" )]
6276)]{
6377
64- Represents an externally defined DTD.}
78+ Represents an externally defined DTD.
79+
80+ As a special case , immediate instances of @racket[external-dtd]
81+ represent the @emph{absence} of an external DTD, and its @racket[system]
82+ field is ignored. The @racket[no-external-dtd] value is provided
83+ for clarity, but any immediate instance of @racket[external-dtd]
84+ has the same meaning.
85+
86+ @examples[
87+ #:eval xml-eval
88+ (define (show-doctype type)
89+ (write-xml (document (prolog '() type '() )
90+ (element #f #f (document-type-name type) '() '() )
91+ '() )))
92+ (show-doctype (document-type 'html (external-dtd "ignored " ) #f ))
93+ (show-doctype (document-type 'svg
94+ (external-dtd/public "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd "
95+ "-//W3C//DTD SVG 1.1//EN " )
96+ #f ))
97+ (show-doctype (document-type 'greeting (external-dtd/system "hello.dtd " ) #f ))
98+ ]
99+
100+ @history[
101+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
102+ #:changed "8.17.0.5 " @elem{Added @racket[no-external-dtd].}
103+ ]}
65104
66105@defstruct[document-type ([name symbol?]
67106 [external external-dtd?]
68107 [inlined #f ])]{
69108
70- Represents a document type.}
109+ Represents a document type. For examples, see @racket[external-dtd].
110+
111+ @history[
112+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
113+ ]}
71114
72115@defstruct[comment ([text string?])]{
73116
74- Represents a comment.}
117+ Represents a comment.
118+
119+ @history[
120+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
121+ ]}
75122
76123@defstruct[(p-i source) ([target-name symbol?]
77124 [instruction string?])]{
78125
79- Represents a processing instruction.}
126+ Represents a processing instruction.
127+
128+ @examples[
129+ #:eval xml-eval
130+ (write-xml (document (prolog (list (p-i #f #f 'xml "version=\"1.0\" " ))
131+ #f
132+ '() )
133+ (element #f #f 'x )
134+ '() ))
135+ ]
136+
137+ @history[
138+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
139+ ]}
80140
81141@defthing[misc/c contract?]{
82142 Equivalent to @racket[(or/c comment? p-i?)]
@@ -86,21 +146,36 @@ Represents a processing instruction.}
86146 [dtd (or/c document-type #f )]
87147 [misc2 (listof misc/c)])]{
88148Represents a document prolog.
89- }
149+
150+ @history[
151+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
152+ ]}
90153
91154@defstruct[document ([prolog prolog?]
92155 [element element?]
93156 [misc (listof misc/c)])]{
94- Represents a document.}
157+ Represents a document.
158+
159+ @history[
160+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
161+ ]}
95162
96163@defstruct[(element source) ([name symbol?]
97164 [attributes (listof attribute?)]
98165 [content (listof content/c)])]{
99- Represents an element.}
166+ Represents an element.
167+
168+ @history[
169+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
170+ ]}
100171
101172@defstruct[(attribute source) ([name symbol?] [value (or/c string? permissive/c)])]{
102173
103- Represents an attribute within an element.}
174+ Represents an attribute within an element.
175+
176+ @history[
177+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
178+ ]}
104179
105180@defthing[content/c contract?]{
106181 Equivalent to @racket[(or/c pcdata? element? entity? comment? cdata? p-i? permissive/c)].
@@ -115,20 +190,65 @@ Represents an attribute within an element.}
115190
116191@defstruct[(entity source) ([text (or/c symbol? valid-char?)])]{
117192
118- Represents a symbolic or numerical entity.}
193+ Represents a symbolic @deftech{entity} reference
194+ or a numerical @deftech{character reference}.
195+
196+ As a special case , this library parses references to the @deftech{predefined entities}
197+ into @racket[pcdata] values, so it does not generate @racket[entity] values containing
198+ @racket['lt ], @racket['gt ], @racket['amp ], @racket['apos ], or @racket['quot ].
199+ Nonetheless, such @racket[entity] values may be created programmatically.
200+
201+ @examples[
202+ #:eval xml-eval
203+ (for/list ([s '(lt gt amp apos quot)])
204+ (with-output-to-string
205+ (λ ()
206+ (write-xml/content (entity #f #f s)))))
207+ (read-xml/element (open-input-string "<x> <>&'" </x> " ))
208+ ]
209+
210+ @history[
211+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
212+ ]}
119213
120214@defstruct[(pcdata source) ([string string?])]{
121215
122- Represents PCDATA content.}
216+ Represents textual content, i.e@._ what the
217+ @link["https://www.w3.org/TR/REC-xml/#dt-chardata " ]{XML specification} calls
218+ @deftech{character data}.
219+
220+ More specifically, this library library has several representations for
221+ @tech{character data} corresponding to different concrete syntaxes in XML.
222+ The @racket[pcdata] struct represents character data that is neither
223+ encoded by a @tech{character reference} or user-defined @tech{entity},
224+ which use @racket[entity], nor written in a @racket[cdata] section.
225+ References to the @tech{predefined entities} can be represented by either @racket[pcdata]
226+ or @racket[entity], but this library always uses @racket[pcdata] when parsing.
227+
228+ @margin-note{The @racket[pcdata] struct is a bit of a misnomer.
229+ In XML, @litchar{PCDATA} is a keyword used to declare that an element contains
230+ ``@link["https://www.w3.org/TR/REC-xml/#sec-mixed-content " ]{mixed content},''
231+ i.e@._ @tech{character data} potentially interspersed with child elements,
232+ but the @racket[pcdata] struct specifically represents @tech{character data}.
233+ Historically, the term meant ``parsed character data.''
234+ }
235+
236+ @history[
237+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
238+ ]}
123239
124240@defstruct[(cdata source) ([string string?])]{
125241
126- Represents CDATA content .
242+ Represents a CDATA section .
127243
128244The @racket[string] field is assumed to be of the form
129245@litchar{<![CDATA[}@nonterm{content}@litchar{]]>} with proper quoting
130246of @nonterm{content}. Otherwise, @racket[write-xml] generates
131- incorrect output.}
247+ ill-formed output.
248+
249+ @history[
250+ #:changed "8.17.0.5 " @elem{Added support for serialization with @racketmodname[racket/serialize].}
251+ ]}
132252
133253@defstruct[(exn:invalid-xexpr exn:fail) ([code any/c])]{
134254
0 commit comments