Support for various windows codepages, thanks to Pierre Mai
[cxml/s11.git] / doc / klacks.xml
blobff617dc4bdcdd5c540003ec68b35804cd0778d57
1 <documentation title="CXML Klacks parser">
2     <h1>Klacks parser</h1>
3     <p>
4       The Klacks parser provides an alternative parsing interface,
5       similar in concept to Java's <a
6       href="http://jcp.org/en/jsr/detail?id=173">Streaming API for
7       XML</a> (StAX).
8     </p>
9     <p>
10       It implements a streaming, "pull-based" API.  This is different
11       from SAX, which is a "push-based" model.
12     </p>
13     <p>
14       Klacks is implemented using the same code base as the SAX parser
15       and has the same parsing characteristics (validation, namespace
16       support, entity resolution) while offering a more flexible interface
17       than SAX.
18     </p>
19     <p>
20       See below for <a href="#examples">examples</a>.
21     </p>
23     <a name="sources"/>
24     <h3>Parsing incrementally using sources</h3>
25     <p>
26       To parse using Klacks, create an XML <tt>source</tt> first.
27     </p>
28     <p>
29       <div class="def">Function CXML:MAKE-SOURCE (input &amp;key validate
30       dtd root entity-resolver disallow-external-subset pathname)</div>
31       Create and return a source for <tt>input</tt>.
32     </p>
33     <p>
34       Exact behaviour depends on <tt>input</tt>, which can
35       be one of the following types:
36     </p>
37     <ul>
38       <li>
39         <tt>pathname</tt> -- a Common Lisp pathname.  
40         Open the file specified by the pathname and create a source for
41         the resulting stream.  See below for information on how to
42         close the stream.
43       </li>
44       <li><tt>stream</tt> -- a Common Lisp stream with element-type
45         <tt>(unsigned-byte 8)</tt>.  See below for information on how to
46         close the stream.
47       </li>
48       <li>
49         <tt>octets</tt> -- an <tt>(unsigned-byte 8)</tt> array.
50         The array is parsed directly, and interpreted according to the
51         encoding it specifies.
52       </li>
53       <li>
54         <tt>string</tt>/<tt>rod</tt> -- a rod (or <tt>string</tt> on
55         unicode-capable implementations).
56         Parses an XML document from the input string that has already
57         undergone external-format decoding.
58       </li>
59     </ul>
60     <p>
61       <b>Closing streams:</b> Sources can refer to Lisp streams that
62       need to be closed after parsing.  This includes a stream passed
63       explicitly as <tt>input</tt>, a stream created implicitly for the
64       <tt>pathname</tt> case, as well as any streams created
65       automatically for external parsed entities referred to by the
66       document.
67     </p>
68     <p>
69       All these stream get closed automatically if end of file is
70       reached normally.  Use <tt>klacks:close-source</tt> or
71       <tt>klacks:with-open-source</tt> to ensure that the streams get
72       closed otherwise.
73     </p>
74     <p>
75       <b>Buffering:</b> By default, the Klacks parser performs buffering
76       of octets being read from the stream as an optimization.  This can
77       result in unwanted blocking if the stream is a socket and the
78       parser tries to read more data than required to parse the current
79       event.  Use <tt>:buffering nil</tt> to disable this optimization.
80     </p>
81     <ul>
82       <li>
83         <tt>buffering</tt> -- Boolean, defaults to <tt>t</tt>.  If
84         enabled, read data several kilobytes at time.  If disabled,
85         read only single bytes at a time.
86       </li>
87     </ul>
88     <p>
89       The following <b>keyword arguments</b> have the same meaning as
90       with the SAX parser, please refer to the documentation of <a
91       href="sax.html#parser">parse-file</a> for more information:
92     </p>
93     <ul>
94       <li>
95         <tt>validate</tt>
96       </li>
97       <li>
98         <tt>dtd</tt>
99       </li>
100       <li><tt>root</tt>
101       </li>
102       <li>
103         <tt>entity-resolver</tt>
104       </li>
105       <li>
106         <tt>disallow-internal-subset</tt>
107       </li>
108     </ul>
109     <p>
110       In addition, the following argument is for types of <tt>input</tt>
111       other than <tt>pathname</tt>:
112     </p>
113     <ul>
114       <li>
115         <tt>pathname</tt> -- If specified, defines the base URI of the
116         document based on this pathname instance.
117       </li>
118     </ul>
120     <p>
121       Events are read from the stream using the following functions:
122     </p>
123       <div class="def">Function KLACKS:PEEK (source)</div>
124      <p> => :start-document<br/>
125           or => :start-document, version, encoding, standalonep<br/>
126           or => :dtd, name, public-id, system-id<br/>
127           or => :start-element, uri, lname, qname<br/>
128           or => :end-element, uri, lname, qname<br/>
129           or => :characters, data<br/>
130           or => :processing-instruction, target, data<br/>
131           or => :comment, data<br/>
132           or => :end-document, data<br/>
133           or => nil
134     </p>
135     <p>
136       <tt>peek</tt> returns the current event's key and main values.
137     </p>
138     <p>
139       <div class="def">Function KLACKS:PEEK-NEXT (source) => key, value*</div>
140     </p>
141     <p>
142       Advance the source forward to the next event and returns it
143       like <tt>peek</tt> would.
144     </p>
145     <p>
146       <div class="def">Function KLACKS:PEEK-VALUE (source) => value*</div>
147     </p>
148     <p>
149       Like <tt>peek</tt>, but return only the values, not the key.
150     </p>
151     <p>
152       <div class="def">Function KLACKS:CONSUME (source) => key, value*</div>
153     </p>
154     <p>
155       Return the same values <tt>peek</tt> would, and in addition
156       advance the source forward to the next event.
157     </p>
158     <p>
159       <div class="def">Function KLACKS:CURRENT-URI (source) => uri</div>
160       <div class="def">Function KLACKS:CURRENT-LNAME (source) => string</div>
161       <div class="def">Function KLACKS:CURRENT-QNAME (source) => string</div>
162     </p>
163     <p>
164      If the current event is :start-element or :end-element, return the
165      corresponding value.  Else, signal an error.
166     </p>
167     <p>
168       <div class="def">Function KLACKS:CURRENT-CHARACTERS (source) => string</div>
169     </p>
170     <p>
171      If the current event is :characters, return the character data
172      value.  Else, signal an error.
173     </p>
174     <p>
175       <div class="def">Function KLACKS:CURRENT-CDATA-SECTION-P (source) => boolean</div>
176     </p>
177     <p>
178      If the current event is :characters, determine whether the data was
179      specified using a CDATA section in the source document.  Else,
180      signal an error.
181     </p>
182     <p>
183       <div class="def">Function KLACKS:MAP-CURRENT-NAMESPACE-DECLARATIONS (fn source) => nil</div>
184     </p>
185     <p>
186      For use only on :start-element and :end-element events, this
187      function report every namespace declaration on the current element.
188      On :start-element, these correspond to the xmlns attributes of the
189      start tag.  On :end-element, the declarations of the corresponding
190      start tag are reported.  No inherited namespaces are
191      included.  <tt>fn</tt> is called only for each declaration with two
192      arguments, the prefix and uri.
193     </p>
194     <p>
195       <div class="def">Function KLACKS:MAP-ATTRIBUTES (fn source)</div>
196     </p>
197     <p>
198      Call <tt>fn</tt> for each attribute of the current start tag in
199      turn, and pass the following values as arguments to the function:
200         <ul>
201           <li>namespace uri</li>
202           <li>local name</li>
203           <li>qualified name</li>
204           <li>attribute value</li>
205           <li>a boolean indicating whether the attribute was specified
206           explicitly in the source document, rather than defaulted from
207           a DTD</li>
208         </ul>
209      Only valid for :start-element.
210     </p>
211     <p>
212      Return a list of SAX attribute structures for the current start tag.
213      Only valid for :start-element.
214     </p>
216     <p>
217       <div class="def">Function KLACKS:CLOSE-SOURCE (source)</div>
218       Close all streams referred to by <tt>source</tt>.
219     </p>
220     <p>
221       <div class="def">Macro KLACKS:WITH-OPEN-SOURCE ((var source) &amp;body body)</div>
222       Evaluate <tt>source</tt> to create a source object, bind it to
223       symbol <tt>var</tt> and evaluate <tt>body</tt> as an implicit progn.
224       Call <tt>klacks:close-source</tt> to close the source after
225       exiting <tt>body</tt>, whether normally or abnormally.
226     </p>
228     <a name="convenience"/>
229     <h3>Convenience functions</h3>
230     <p>
231       <div class="def">Function KLACKS:FIND-EVENT (source key)</div>
232       Read events from <tt>source</tt> and discard them until an event
233       of type <i>key</i> is found.  Return values like <tt>peek</tt>, or
234       NIL if no such event was found.
235     </p>
236     <p>
237       <div class="def">Function KLACKS:FIND-ELEMENT (source &amp;optional
238       lname uri)</div>
239       Read events from <tt>source</tt> and discard them until an event
240       of type :start-element is found with matching local name and
241       namespace uri is found.   If <tt>lname</tt> is <tt>nil</tt>, any
242       tag name matches.  If <tt>uri</tt> is <tt>nil</tt>, any
243       namespace matches. Return values like <tt>peek</tt> or NIL if no
244       such event was found.
245     </p>
246     <p>
247       <div class="def">Condition KLACKS:KLACKS-ERROR (xml-parse-error)</div>
248       The condition class signalled by <tt>expect</tt>.
249     </p>
250     <p>
251       <div class="def">Function KLACKS:EXPECT (source key &amp;optional
252       value1 value2 value3)</div>
253       Assert that the current event is equal to (key value1 value2
254       value3).  (Ignore <i>value</i> arguments that are NIL.)  If so,
255       return it as multiple values.  Otherwise signal a
256       <tt>klacks-error</tt>.
257     </p>
258     <p>
259       <div class="def">Function KLACKS:SKIP (source key &amp;optional
260       value1 value2 value3)</div>
261       <tt>expect</tt> the specific event, then <tt>consume</tt> it.
262     </p>
263     <p>
264       <div class="def">Macro KLACKS:EXPECTING-ELEMENT ((fn source
265       &amp;optional lname uri) &amp;body body</div>
266       Assert that the current event matches (:start-element uri lname).
267       (Ignore <i>value</i> arguments that are NIL)  Otherwise signal a
268       <tt>klacks-error</tt>.
269       Evaluate <tt>body</tt> as an implicit progn.  Finally assert that
270       the remaining event matches (:end-element uri lname).
271     </p>
273     <a name="klacksax"/>
274     <h3>Bridging Klacks and SAX</h3>
275     <p>
276       <div class="def">Function KLACKS:SERIALIZE-EVENT (source handler)</div>
277       Send the current klacks event from <tt>source</tt> as a SAX
278       event to the SAX <tt>handler</tt> and consume it.
279     </p>
280     <p>
281       <div class="def">Function KLACKS:SERIALIZE-ELEMENT (source handler
282       &amp;key document-events)</div>
283       Read all klacks events from the following <tt>:start-element</tt> to
284       its <tt>:end-element</tt> and send them as SAX events
285       to <tt>handler</tt>.  When this function is called, the current
286       event must be <tt>:start-element</tt>, else an error is
287       signalled.  With <tt>document-events</tt> (the default),
288       <tt>sax:start-document</tt> and <tt>sax:end-document</tt> events
289       are sent around the element.
290     </p>
291     <p>
292       <div class="def">Function KLACKS:SERIALIZE-SOURCE (source handler)</div>
293       Read all klacks events from <tt>source</tt> and send them as SAX
294       events to the SAX <tt>handler</tt>.
295     </p>
296     <p>
297       <div class="def">Class KLACKS:TAPPING-SOURCE (source)</div>
298       A klacks source that relays events from an upstream klacks source
299       unchanged, while also emitting them as SAX events to a
300       user-specified handler at the same time.
301     </p>
302     <p>
303       <div class="def">Functon KLACKS:MAKE-TAPPING-SOURCE
304       (upstream-source &amp;optional sax-handler)</div>
305       Create a tapping source relaying events
306       for <tt>upstream-source</tt>, and sending SAX events
307       to <tt>sax-handler</tt>.
308     </p>
310     <a name="locator"/>
311     <h3>Location information</h3>
312     <p>
313       <div class="def">Function KLACKS:CURRENT-LINE-NUMBER (source)</div>
314       Return an approximation of the current line number, or NIL.
315     </p>
316     <p>
317       <div class="def">Function KLACKS:CURRENT-COLUMN-NUMBER (source)</div>
318       Return an approximation of the current column number, or NIL.
319     </p>
320     <p>
321       <div class="def">Function KLACKS:CURRENT-SYSTEM-ID (source)</div>
322       Return the URI of the document being parsed.  This is either the
323     main document, or the entity's system ID while contents of a parsed
324     general external entity are being processed.
325     </p>
326     <p>
327       <div class="def">Function KLACKS:CURRENT-XML-BASE (source)</div>
328       Return the [Base URI] of the current element.  This URI can differ from
329    the value returned by <tt>current-system-id</tt> if xml:base
330       attributes are present.
331     </p>
333     <a name="examples"/>
334     <h3>Examples</h3>
335     <p>
336       The following example illustrates creation of a klacks <tt>source</tt>,
337       use of the <tt>peek-next</tt> function to read individual events,
338       and shows some of the most common event types.
339     </p>
340     <pre>* <b>(defparameter *source* (cxml:make-source "&lt;example>text&lt;/example>"))</b>
341 *SOURCE*
343 * <b>(klacks:peek-next *source*)</b>
344 :START-DOCUMENT
346 * <b>(klacks:peek-next *source*)</b>
347 :START-ELEMENT
348 NIL                      ;namespace URI
349 "example"                ;local name
350 "example"                ;qualified name
352 * <b>(klacks:peek-next *source*)</b>
353 :CHARACTERS
354 "text"
356 * <b>(klacks:peek-next *source*)</b>
357 :END-ELEMENT
359 "example"
360 "example"
362 * <b>(klacks:peek-next *source*)</b>
363 :END-DOCUMENT
365 * <b>(klacks:peek-next *source*)</b>
366 NIL</pre>
368     <p>
369       In this example, <tt>find-element</tt> is used to skip over the
370       uninteresting events until the opening <tt>child1</tt> tag is
371       found.  Then <tt>serialize-element</tt> is used to generate SAX
372       events for the following element, including its children, and an
373       xmls-compatible list structure is built from those
374       events.  <tt>find-element</tt> skips over whitespace,
375       and <tt>find-event</tt> is used to parse up
376       to <tt>:end-document</tt>, ensuring that the source has been
377       closed.
378     </p>
379     <pre>* <b>(defparameter *source*
380       (cxml:make-source "&lt;example>
381                            &lt;child1>&lt;p>foo&lt;/p>&lt;/child1>
382                            &lt;child2 bar='baz'/>
383                          &lt;/example>"))</b>
384 *SOURCE*
386 * <b>(klacks:find-element *source* "child1")</b>
387 :START-ELEMENT
389 "child1"
390 "child1"
392 * <b>(klacks:serialize-element *source* (cxml-xmls:make-xmls-builder))</b>
393 ("child1" NIL ("p" NIL "foo"))
395 * <b>(klacks:find-element *source*)</b>
396 :START-ELEMENT
398 "child2"
399 "child2"
401 *  <b>(klacks:serialize-element *source* (cxml-xmls:make-xmls-builder))</b>
402 ("child2" (("bar" "baz")))
404 * <b>(klacks:find-event *source* :end-document)</b>
405 :END-DOCUMENT
409 </pre>
410 </documentation>