various docstrings; release
[cxml/s11.git] / doc / sax.xml
blobb708a4617ef8d5f7826799ab455b8b4bb2b0ef98
1 <documentation title="CXML SAX parser">
2     <h1>SAX parsing and serialization</h1>
4     <a name="parser"/>
6     <p>
7       This chapter describes CXML's SAX-like parser interface.
8     </p>
9     <p>
10       The SAX layer is an important concept in CXML that users will
11       encounter in various situations:
12     </p>
13     <ul>
14       <li>
15         To <b>parse into DOM</b>, use the SAX parser as described below with
16         a <b>DOM builder</b> as the SAX handler.  (Refer to <a
17         href="dom.html#parser">make-dom-builder</a> for information about
18         DOM.)
19       </li>
20       <li>
21         <b>Serialization</b> is done using SAX, too.   SAX handlers that
22         process and consume events without sending them to another
23         handler are called <i>sinks</i> in CXML.  Serialization sinks
24         write XML output for the events they receive.  For example, to
25         serialize DOM, use <tt>map-document</tt> to turn the DOM
26         document into SAX events together with a <tt>sink</tt> for
27         serialization.
28       </li>
29       <li>
30         SAX handlers can be chained together.  Various SAX handlers
31         are offered that can be used in this way, transforming SAX
32         events before handing them to the next handler.  This includes
33         handlers for <b>whitespace removal</b>, <b>namespace
34         normalization</b>, and rod-to-string <b>recoding</b>.
35       </li>
36     </ul>
37     <p>
38       However, SAX events are easier to generate than to process.  That
39       is why CXML offers <i>Klacks</i>, a "pull-based" API in addition to SAX.
40       Klacks events are generally easier to process than to generate.
41       Please refer to the <a href="klacks.html">Klacks documentation</a>
42       for details.
43     </p>
45     <h3>Parsing and Validating</h3>
46     <div style="border: 1px dotted black;
47                 width: 70%;
48                 padding: 1em">
49     <p>
50       Old-style convenience functions:
51     </p>
52     <div style="font-weight: bold">Function CXML:PARSE-FILE (pathname handler &amp;key ...)</div>
53     <p style="margin-left: 2em">Same as <tt>cxml:parse</tt> with a pathname argument.
54       (But note that <tt>cxml:parse-file</tt> interprets string
55       arguments as namestrings, while <tt>cxml:parse</tt> expects
56       literal XML documents.)
57     </p>
58     <div style="font-weight: bold">Function CXML:PARSE-STREAM (stream handler &amp;key ...)</div>
59     <p style="margin-left: 2em">Same as <tt>cxml:parse</tt> with a stream argument.</p>
60     <div style="font-weight: bold">Function CXML:PARSE-OCTETS (octets handler &amp;key ...)</div>
61     <p style="margin-left: 2em">Same as <tt>cxml:parse</tt> with an octet vector argument.</p>
62     <div style="font-weight: bold">Function CXML:PARSE-ROD (rod handler &amp;key ...)</div>
63     <p style="margin-left: 2em">Same as <tt>cxml:parse</tt> with a string argument.</p>
64     </div>
66     <h4>
67       New all-in-one parser interface:
68     </h4>
69     <div class="def">Function CXML:PARSE (input handler &amp;key ...)</div>
70     <p>
71       Parse an XML document, where input is a string, pathname, octet
72       vector, or stream.
73       Return values from this function depend on the SAX handler used.<br/>
74       Arguments:
75     </p>
76     <ul>
77       <li>
78         <tt>input</tt> -- one of:<br/>
79         <ul>
80           <li>
81             <tt>pathname</tt> -- a Common Lisp pathname.  
82             Open the file specified by the pathname and parse its
83             contents as an XML document. 
84           </li>
85           <li><tt>stream</tt> -- a Common Lisp stream with element-type
86             <tt>(unsigned-byte 8)</tt>.
87           </li>
88           <li>
89             <tt>octets</tt> -- an <tt>(unsigned-byte 8)</tt> array.
90             The array is parsed directly, and interpreted according to the
91             encoding it specifies.
92           </li>
93           <li>
94             <tt>string</tt>/<tt>rod</tt> -- a rod (or <tt>string</tt> on
95             unicode-capable implementations).
96             Parses an XML document from the input string that has already
97             undergone external-format decoding.
98           </li>
99         </ul>
100       </li>
101       <li><tt>stream</tt> -- a Common Lisp stream with element-type
102         <tt>(unsigned-byte 8)</tt></li>
103       <li><tt>octets</tt> -- an <tt>(unsigned-byte 8)</tt> array</li>
104       <li><tt>handler</tt> -- a SAX handler</li>
105     </ul>
106     <p>
107       Common keyword arguments:
108     </p>
109     <ul>
110       <li>
111         <tt>validate</tt> -- A boolean.&#160; Defaults to
112         <tt>nil</tt>.  If true, parse in validating mode, i.e. assert that
113         the document contains a DOCTYPE declaration and conforms to the
114         DTD declared.
115       </li>
116       <li>
117         <tt>dtd</tt> -- unless <tt>nil</tt>, an extid instance
118         specifying the external subset to load.  This options overrides
119         the extid specified in the document type declaration, if any.
120         See below for <tt>make-extid</tt>.  This option is useful
121         for verification purposes together with the <tt>root</tt>
122         and <tt>disallow-internal-subset</tt> arguments.
123       </li>
124       <li><tt>root</tt> -- the expected root element
125         name, or <tt>nil</tt> (the default).
126       </li>
127       <li>
128         <tt>entity-resolver</tt> -- <tt>nil</tt> or a function of two
129         arguments which is invoked for every entity referenced by the
130         document with the entity's Public ID (a rod) and System ID (an
131         URI object) as arguments.  The function may either return
132         nil, CXML will then try to resolve the entity as usual.
133         Alternatively it may return a Common Lisp stream specialized on
134         <tt>(unsigned-byte 8)</tt> which will be used instead.  (It may
135         also signal an error, of course, which can be useful to prohibit
136         parsed XML documents from including arbitrary files readable by
137         the parser.)
138       </li>
139       <li>
140         <tt>disallow-internal-subset</tt> -- a boolean.  If true, signal
141         an error if the document contains an internal subset.
142       </li>
143       <li>
144         <tt>recode</tt> -- a boolean.  (Ignored on Lisps with Unicode
145         support.)  Recode rods to UTF-8 strings.  Defaults to true.
146         Make sure to use <tt>utf8-dom:make-dom-builder</tt> if this
147         option is enabled and <tt>rune-dom:make-dom-builder</tt>
148         otherwise.
149       </li>
150     </ul>
151     <p>
152       Note: <tt>parse-rod</tt> assumes that the input has already been
153       decoded into Unicode runes and ignores the encoding
154       specified in the XML declaration, if any.
155     </p>
157     <p>
158       <div class="def">Function CXML:PARSE-EMPTY-DOCUMENT (uri qname handler &amp;key public-id system-id entity-resolver recode)</div>
159     </p>
160     <p>
161       Simulate parsing a document with a document element <tt>qname</tt>
162       having no attributes except for an optional namespace
163       declaration to <tt>uri</tt>.  If an external ID is specified
164       (<tt>system-id</tt>, <tt>public-id</tt>), find, parse, and report
165       this DTD as if with <tt>parse-file</tt>, using the specified
166       entity resolver.
167     </p>
169     <p>
170       <div class="def">Function CXML:PARSE-DTD-FILE (pathname)</div>
171       <div class="def">Function CXML:PARSE-DTD-STREAM (stream)</div>
172       Parse <a
173       href="http://www.w3.org/TR/2000/REC-xml-20001006#NT-extSubset">declarations</a>
174       from a stand-alone file and return an object representing the DTD,
175       suitable as an argument to <tt>validate</tt>.
176     </p>
177     <ul>
178       <li><tt>pathname</tt> -- a Common Lisp pathname</li>
179       <li><tt>stream</tt> -- a Common Lisp stream with element-type
180         <tt>(unsigned-byte 8)</tt></li>
181     </ul>
183     <p>
184       <div class="def">Function CXML:MAKE-EXTID (publicid systemid)</div>
185       Create an object representing the External ID composed
186       of the specified Public ID, a rod or <tt>nil</tt>, and System ID
187       (an URI object).
188     </p>
190     <p>
191       <div class="def">Condition class CXML:XML-PARSE-ERROR ()</div>
192       Superclass of all conditions signalled by the CXML parser.
193     </p>
194     <p>
195       <div class="def">Condition class CXML:WELL-FORMEDNESS-VIOLATION (cxml:xml-parse-error)</div>
196       This condition is signalled for all well-formedness violations.
197       (Note that, when parsing document that is not well-formed in validating
198       mode, the parser might encounter validity errors before detecting
199       well-formedness problems, so also be prepared for <tt>validity-error</tt>
200       in that situation.)
201     </p>
202     <p>
203       <div class="def">Condition class CXML:VALIDITY-ERROR (cxml:xml-parse-error)</div>
204       Reports the violation of a validity constraint.
205     </p>
207     <a name="serialization"/>
208     <h3>Serialization</h3>
209     <p>
210       Serialization is performed using <tt>sink</tt> objects.  There are
211       different kinds of sinks for output to lisp streams and vectors in
212       various flavours.
213     </p>
214     <p>
215       Technically, sinks are SAX handlers that write XML output for SAX
216       events sent to them.  In practise, user code would normally not
217       generate those SAX events manually, and instead use a function
218       like <a href="dom.html#serialization">dom:map-document</a> or <a
219       href="xmls-compat.html">xmls-compat:map-node</a> to serialize an
220       in-memory document.
221     </p>
222     <p>
223       In addition to <tt>map-document</tt>, cxml has a set of
224       convenience macros for serialization (see below for
225       <tt>with-xml-output</tt>, <tt>with-element</tt>, etc).
226     </p>
228     <div style="background-color: #ddddff">
229       Portable sinks:<br/>
230       <span class="def">Function CXML:MAKE-OCTET-VECTOR-SINK (&amp;rest keys) => sink</span><br/>
231       <span class="def">Function CXML:MAKE-OCTET-STREAM-SINK (stream &amp;rest keys) => sink</span><br/>
232       <span class="def">Function CXML:MAKE-ROD-SINK (&amp;rest keys) => sink</span><br/>
233       <br/>
234       Only on Lisps with Unicode support:<br/>
235       <span class="def">Function CXML:MAKE-STRING-SINK</span> -- alias for <tt>cxml:make-rod-sink</tt><br/>
236       <span class="def">Function CXML:MAKE-CHARACTER-STREAM-SINK (stream &amp;rest keys) => sink</span><br/>
237       <br/>
238       Only on Lisps <em>without</em> Unicode support:<br/>
239       <span class="def">Function CXML:MAKE-STRING-SINK/UTF8 (&amp;rest keys) => sink</span><br/>
240       <span class="def">Function CXML:MAKE-CHARACTER-STREAM-SINK/UTF8 (stream &amp;rest keys) => sink</span><br/>
241     </div>
242     <p>
243       Return a SAX serialization handle.
244     </p>
245     <ul>
246       <li>
247         The <tt>-octet-</tt> functions write the document encoded into
248         UTF-8.
249         <tt>make-octet-stream-sink</tt> works with Lisp streams of
250         element-type <tt>(unsigned-byte 8)</tt>.
251         <tt>make-octet-vector-sink</tt> returns a vector of
252         <tt>(unsigned-byte 8)</tt>.
253       </li>
254       <li>
255         <tt>make-character-stream-sink</tt> works with character
256         streams.  It serializes the document into characters <em>without
257         encoding it into an external format</em>.  When using these
258         functions, <em>take care to avoid encoding the result into
259         an incorrect external format</em>.  (Note that characters undergo
260         external format conversion when written to a character stream.
261         If the document's XML declaration specifies an encoding, make
262         sure to specify this encoding as the external format if and when
263         writing the serialized document to a character stream.  If the
264         document does not specify an encoding, either UTF-8 or UTF-16
265         must be used.)  This function is available only on Lisps with
266         unicode support.
267       </li>
268       <li>
269         <tt>make-rod-sink</tt> serializes the document into a vector of
270         runes <em>without encoding it into an external format</em>.
271         (On Lisp with unicode support, the result will be a string;
272         otherwise, a vector of character codes will be returned.)
273         The warnings given for <tt>make-character-stream-sink</tt>
274         apply to this function as well.
275       </li>
276       <li>
277         The <tt>/utf8</tt> functions write the document encoded into
278         characters representing a UTF-8 encoding.
279         When using these functions, <em>take care to avoid encoding the
280         result</em> into an external format for a second time.  (Note
281         that characters undergo external format conversion when written
282         to a character stream.  Since these functions already perform
283         external format conversion, make sure to specify an external
284         format that does "nothing" if and when writing the serialized document
285         to a character stream.  ISO-8859-1 external formats usually
286         achieve the desired effect.)
287         <tt>make-character-stream-sink/utf8</tt> works with character streams.
288         <tt>make-string-sink/utf8</tt> returns a string.
289         These functions are available only on Lisps without unicode support.
290       </li>
291     </ul>
292     <p>Keyword arguments:</p>
293     <ul>
294       <li>
295         <tt>canonical</tt> -- canonical form, one of NIL, T, 1, 2
296       </li>
297       <li>
298         <tt>indentation</tt> -- indentation level.  An integer or <tt>nil</tt>.
299       </li>
300       <li>
301         <tt>encoding</tt> -- the character encoding to use.  A string or
302         keyword.  <tt>nil</tt> is also allowed and means UTF-8.
303       </li>
304       <li>
305         <tt>omit-xml-declaration-p</tt> -- Boolean.  Don't write an XML
306         declaration.
307       </li>
308     </ul>
309     <p>
310       The following <tt>canonical</tt> values are allowed:
311     </p>
312     <ul>
313       <li>
314         <tt>t</tt> or <tt>1</tt>: <a
315          href="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">Canonical
316          XML</a>
317       </li>
318       <li>
319         <tt>2</tt>: <a
320          href="http://dev.w3.org/cvsweb/~checkout~/2001/XML-Test-Suite/xmlconf/sun/cxml.html?content-type=text/html;%20charset=iso-8859-1">Second
321          Canonical Form</a>
322       </li>
323       <li>
324         <tt>NIL</tt>: Use a more readable non-canonical representation.
325       </li>
326     </ul>
327     <p>
328       An internal subset will be included in the result regardless of
329       the <tt>canonical</tt> setting.  It is the responsibility of the
330       caller to not report an internal subset for
331       canonical&#160;&lt;=&#160;1, or only notations as required for
332       canonical&#160;=&#160;2.  For example, the
333       <tt>include-doctype</tt> argument to <tt>dom:map-document</tt>
334       should be set to <tt>nil</tt> for the former behaviour and
335       <tt>:canonical-notations</tt> for the latter.
336     </p>
337     <p>
338       With an <tt>indentation</tt> level, pretty-print the XML by
339       inserting additional whitespace.&#160; Note that indentation
340       changes the document model and should only be used if whitespace
341       does not matter to the application.
342     </p>
344     <p>
345       <div class="def">Macro CXML:WITH-XML-OUTPUT (sink &amp;body body) => sink-specific result</div>
346       <div class="def">Macro CXML:WITH-NAMESPACE ((prefix uri) &amp;body body) => result</div>
347       <div class="def">Macro CXML:WITH-ELEMENT (qname &amp;body body) => result</div>
348       <div class="def">Macro CXML:WITH-ELEMENT* ((prefix lname) &amp;body body) => result</div>
349       <div class="def">Function CXML:ATTRIBUTE (qname value) => value</div>
350       <div class="def">Generic Function CXML:UNPARSE-ATTRIBUTE (value) => string</div>
351       <div class="def">Function CXML:ATTRIBUTE* (prefix lname value) => value</div>
352       <div class="def">Function CXML:TEXT (data) => data</div>
353       <div class="def">Function CXML:CDATA (data) => data</div>
354       <div class="def">Function CXML:doctype (name public-id system-id &amp;optional internal-subset)</div>
355       Convenience syntax for event-based serialization.
356     </p>
357     <p>
358       Example:
359     </p>
360     <pre>(with-xml-output (make-octet-stream-sink stream :indentation 2 :canonical nil)
361   (with-element "foo"
362     (attribute "xyz" "abc")
363     (with-element "bar"
364       (attribute "blub" "bla"))
365     (text "Hi there.")))</pre>
366    <p>
367       Prints this to <tt>stream</tt>:
368    </p>
369    <pre>&lt;foo xyz="abc"&gt;
370   &lt;bar blub="bla"&gt;&lt;/bar&gt;
371   Hi there.
372 &lt;/foo&gt;</pre>
374     <p>
375       <div class="def">Macro XHTML-GENERATOR:WITH-XHTML (sink &amp;rest forms)</div>
376       <div class="def">Macro XHTML-GENERATOR:WRITE-DOCTYPE (sink)</div>
377       Macro <tt>with-xhtml</tt> is a modified version of
378       Franz' <tt>htmlgen</tt> works as a SAX driver for XHTML.
379       It aims to be a plug-in replacement for the <tt>html</tt> macro.
380     </p>
381     <p>
382       <tt>xhtmlgen</tt> is included as <tt>contrib/xhtmlgen.lisp</tt> in
383       the cxml distribution.  Example:
384     </p>
385     <pre>(let ((sink (cxml:make-character-stream-sink *standard-output*)))
386   (sax:start-document sink)
387   (xhtml-generator:write-doctype sink)
388   (xhtml-generator:with-html sink
389     (:html
390      (:head
391       (:title "Titel"))
392      (:body
393       ((:p "style" "font-weight: bold")
394        "Inhalt")
395       (:ul
396        (:li "Eins")
397        (:li "Zwei")
398        (:li "Drei")))))
399   (sax:end-document sink))</pre>
401     <a name="misc"/>
402     <h3>Miscellaneous SAX handlers</h3>
403     <p>
404       <div class="def">Function CXML:MAKE-VALIDATOR (dtd root)</div>
405       Create a SAX handler which validates against a DTD instance.&#160;
406       The document's root element must be named <tt>root</tt>.&#160; 
407       Used with <tt>dom:map-document</tt>, this validates a document
408       object as if by re-reading it with a validating parser, except
409       that declarations recorded in the document instance are completely
410       ignored.<br/>
411       Example:
412     </p>
413     <pre>(let ((d (parse-file "~/test.xml" (cxml-dom:make-dom-builder)))
414       (x (parse-dtd-file "~/test.dtd")))
415   (dom:map-document (cxml:make-validator x #"foo") d))</pre>
417     <p>
418       <div class="def">Class CXML:BROADCAST-HANDLER ()</div>
419       <div class="def">Accessor CXML:BROADCAST-HANDLER-HANDLERS</div>
420       <div class="def">Function CXML:MAKE-BROADCAST-HANDLER (&amp;rest handlers)</div>
421       <tt>broadcast-handler</tt> is a SAX handler which passes every event it
422       receives on to each of several chained handlers, somewhat similar
423       to the way a <tt>broadcast-stream</tt> works.
424     </p>
425     <p>
426       You can subclass <tt>broadcast-stream</tt> to modify the events
427       before they are being passed on.  Define methods on your handler
428       class for the events to be modified.  All other events will pass
429       through to the chained handlers unmodified.
430     </p>
431     <p>
432       Broadcast handler functions return the result of calling the event
433       function on the <i>last</i> handler in the list.  In particular,
434       the overall result from <tt>sax:end-document</tt> will be ignored
435       for all other handlers.
436     </p>
438     <p>
439       <div class="def">Class CXML:SAX-PROXY (broadcast-handler)</div>
440       <div class="def">Accessor CXML:PROXY-CHAINED-HANDLER</div>
441       <tt>sax-proxy</tt> is a subclass of <tt>broadcast-handler</tt>
442       which sends events to exactly one chained handler.  This class is
443       still included for compatibility with older versions of
444       CXML which did not include the more
445       general <tt>broadcast-handler</tt> yet, but has been retrofitted
446       as a subclass of the latter.
447     </p>
449     <p>
450     <div class="def">Accessor CXML:MAKE-NAMESPACE-NORMALIZER (next-handler)</div>
451     </p>
452     <p>
453       Return a SAX handler that performs <a
454       href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#normalizeDocumentAlgo">DOM
455       3-style namespace normalization</a> on attribute lists in
456       <tt>start-element</tt> events before passing them on the next
457       handler.
458     </p>
459     <p>
460       <div class="def">Function CXML:MAKE-WHITESPACE-NORMALIZER (chained-handler &amp;optional dtd)</div>
461       Return a SAX handler which removes whitespace from elements that
462       have <em>element content</em> and have not been declared to
463       preserve space using an xml:space attribute.
464     </p>
465     <p>Example:</p>
466     <pre>(cxml:parse-file "example.xml"
467                  (cxml:make-whitespace-normalizer (cxml-dom:make-dom-builder))
468                  :validate t)</pre>
469     <p>Example input:</p>
470     <pre>&lt;!DOCTYPE test [
471 &lt;!ELEMENT test (foo,bar*)>
472 &lt;!ATTLIST test a CDATA #IMPLIED>
473 &lt;!ELEMENT foo #PCDATA>
474 &lt;!ELEMENT bar (foo?)>
475 &lt;!ATTLIST bar xml:space (default|preserve) "default">
477 &lt;test a='b'>
478   &lt;foo>   &lt;/foo>
479   &lt;bar>   &lt;/bar>
480   &lt;bar xml:space="preserve">   &lt;/bar>
481 &lt;/test>
482 </pre>
483     <p>Example result:</p>
484     <pre>&lt;test a="b">&lt;foo>   &lt;/foo>&lt;bar>&lt;/bar>&lt;bar xml:space="preserve">   &lt;/bar>&lt;/test></pre>
486     <a name="rods"/>
487     <h3>Recoders</h3>
488     <p>
489       Recoders are a mechanism used by CXML internally on Lisp implementations
490       without Unicode support to recode UTF-16 vectors (rods) of
491       integers (runes) into UTF-8 strings.
492     </p>
493     <p>
494       User code does not usually need to deal with recoders in current
495       versions of CXML.
496     </p>
497     <p>
498       <div class="def">Function CXML:MAKE-RECODER (chained-handler recoder-fn)</div>
499       Return a SAX handler which passes all events on to
500       <tt>chained-handler</tt> after converting all strings and rods
501       using <tt>recoder-fn</tt>, a function of one argument.
502     </p>
504     <a name="dtdcache"/>
505     <h3>Caching of DTD Objects</h3>
506     <p>
507       To avoid spending time parsing the same DTD over and over again,
508       CXML can cache DTD objects.  The parser consults
509       <tt>cxml:*dtd-cache*</tt> whenever it is looking for an external
510       subset in a document which does not have an internal subset and
511       uses the cached DTD instance if one is present in the cache for
512       the System ID in question.
513     </p>
514     <p>
515       Note that DTDs do not expire from the cache automatically.
516       (Future versions of CXML might introduce automatic checks for
517       outdated DTDs.)
518     </p>
519     <p>
520       <div class="def">Variable CXML:*DTD-CACHE*</div>
521       The DTD cache object consulted by the parser when it needs a DTD.
522     </p>
523     <p>
524       <div class="def">Function CXML:MAKE-DTD-CACHE ()</div>
525       Return a new, empty DTD cache object.
526     </p>
527     <p>
528       <div class="def">Variable CXML:*CACHE-ALL-DTDS*</div>
529       If true, instructs the parser to enter all DTDs that could have
530       been cached into <tt>*dtd-cache*</tt> if they were not cached
531       already.  Defaults to <tt>nil</tt>.
532     </p>
533     <p>
534       <div class="def">Reader CXML:GETDTD (uri dtd-cache)</div>
535       Return a cached instance of the DTD at <tt>uri</tt>, if present in
536       the cache, or <tt>nil</tt>.
537     </p>
538     <p>
539       <div class="def">Writer CXML:GETDTD (uri dtd-cache)</div>
540       Enter a new value for <tt>uri</tt> into <tt>dtd-cache</tt>.
541     </p>
542     <p>
543       <div class="def">Function CXML:REMDTD (uri dtd-cache)</div>
544       Ensure that no DTD is recorded for <tt>uri</tt> in the cache and
545       return true if such a DTD was present.
546     </p>
547     <p>
548       <div class="def">Function CXML:CLEAR-DTD-CACHE (dtd-cache)</div>
549       Remove all entries from <tt>dtd-cache</tt>.
550     </p>
551     <p>
552       <em>fixme:</em> thread-safety
553     </p>
555     <a name="saxparser"/>
556     <h3>Location information</h3>
557     <p>
558       <div class="def">Class SAX:SAX-PARSER ()</div>
559       A class providing location information through an
560       implementation-specific subclass.  Parsers will use
561       <tt>sax:register-sax-parser</tt> to pass their parser instance to
562       the handler.  The easiest way to receive sax parsers instances is
563       to inherit from sax-parser-mixin when defining a sax handler.
564     </p>
565     <p>
566       <div class="def">Class SAX:SAX-PARSER-MIXIN ()</div>
567       A mixin for sax handler classes that records the sax handler
568       object for use with the following functions.  Trampoline methods
569       are provided that allow those functions to be called directly on
570       the sax-parser-mixin.
571     </p>
572     <p>
573       <div class="def">Function SAX:SAX-HANDLER (sax-handler-mixin) => sax-handler</div>
574       Return the sax-parser instance recorded by this handler, or NIL.
575     </p>
576     <p>
577       <div class="def">Function SAX:LINE-NUMBER (sax-parser)</div>
578       Return an approximation of the current line number, or NIL.
579     </p>
580     <p>
581       <div class="def">Function SAX:COLUMN-NUMBER (sax-parser)</div>
582       Return an approximation of the current column number, or NIL.
583     </p>
584     <p>
585       <div class="def">Function SAX:SYSTEM-ID (sax-parser)</div>
586       Return the URI of the document being parsed.  This is either the
587     main document, or the entity's system ID while contents of a parsed
588     general external entity are being processed.
589     </p>
590     <p>
591       <div class="def">Function SAX:XML-BASE (sax-parser)</div>
592       Return the [Base URI] of the current element.  This URI can differ from
593    the value returned by <tt>sax:system-id</tt> if xml:base
594       attributes are present.
595     </p>
597     <a name="catalogs"/>
598     <h3>XML Catalogs</h3>
599     <p>
600       External entities (for example, DTDs) are referred to using their
601       Public and System IDs.  Usually the System ID, a URI, is used to
602       locate the entity.  CXML itself handles only file://-URIs, but
603       many System IDs in practical use are http://-URIs.  There are two
604       different mechanims applications can use to allow CXML to locate
605       entities using arbitrary Public ID or System ID:
606     </p>
607     <ul>
608       <li>
609         User-defined entity resolvers can be used to open entities using
610         arbitrary protocols.   For example, an entity resolver could
611         handle all System-IDs with the <tt>http</tt> scheme using some
612         HTTP library.  Refer to the description of the 
613         <tt>entity-resolver</tt> keyword argument to parser functions (see <a
614         href="#parser"><tt>cxml:parse-file</tt></a>) to more
615         information on entity resolvers.
616       </li>
617       <li>
618         XML Catalogs are (local) tables in XML syntax which map External
619         IDs to alternative System IDs.  If, say, the xhtml DTD is
620         present in the local file system and the local copy has been
621         registered with the XML catalog, CXML will use the local copy of
622         the DTD instead of trying to open the version available using HTTP.
623       </li>
624     </ul>
625     <p>
626       This section describes XML Catalogs, the second solution.  CXML
627       implements <a
628       href="http://www.oasis-open.org/committees/entity/spec.html">Oasis
629       XML Catalogs</a>.
630     </p>
631     <p>
632       <div class="def">Variable CXML:*CATALOG*</div>
633       The XML Catalog object consulted by the parser before trying to
634       open an entity.  Initially <tt>nil</tt>.
635     </p>
636     <p>
637       <div class="def">Variable CXML:*PREFER*</div>
638       The default "prefer" mode from the Catalog specification, one
639       of <tt>:public</tt> or <tt>:system</tt>.  Defaults
640       to <tt>:public</tt>.
641     </p>
642     <p>
643       <div class="def">Function CXML:MAKE-CATALOG (&amp;optional uris)</div>
644       Return a catalog object for the catalog files specified.
645     </p>
646     <p>
647       <div class="def">Function CXML:RESOLVE-URI (uri catalog)</div>
648       Look up <tt>uri</tt> in <tt>catalog</tt> and return the
649       resulting URI, or <tt>nil</tt> if no match was found.
650     </p>
651     <p>
652       <div class="def">Function CXML:RESOLVE-EXTID (publicid systemid catalog)</div>
653       Look up the External ID (<tt>publicid</tt>, <tt>systemid</tt>)
654       in <tt>catalog</tt> and return the resulting URI, or <tt>nil</tt>
655       if no match was found.
656     </p>
657     <p>
658       Example:
659     </p>
660     <pre>* (setf cxml:*catalog* nil)
661 * (cxml:parse-file "test.xhtml" nil)
662 => Error: URI scheme :HTTP not supported
664 * (setf cxml:*catalog* (cxml:make-catalog))
665 * (cxml:parse-file "test.xhtml" nil)
666 ;; no error!
667 NIL</pre>
668     <p>
669       Note that parsed catalog files are cached in the catalog object.
670       Catalog files cached do not expire automatically.  To ensure that
671       all catalog files are parsed again, create a new catalog object.
672     </p>
674     <a name="sax"/>
675     <h2>SAX Interface</h2>
676     <p>
677       A SAX handler is an arbitrary objects that implements some of the
678       generic functions in the SAX package.&#160; Note that no default
679       handler class is necessary, because all generic functions have default
680       methods which do nothing.&#160; SAX functions are:
681       <div class="def">Function SAX:START-DOCUMENT (handler)</div>
682       <div class="def">Function SAX:END-DOCUMENT (handler)</div>
683       <br/>
684       <div class="def">Function SAX:START-ELEMENT (handler namespace-uri local-name qname attributes)</div>
685       <div class="def">Function SAX:END-ELEMENT (handler namespace-uri local-name qname)</div>
686       <div class="def">Function SAX:START-PREFIX-MAPPING (handler prefix uri)</div>
687       <div class="def">Function SAX:END-PREFIX-MAPPING (handler prefix)</div>
688       <div class="def">Function SAX:PROCESSING-INSTRUCTION (handler target data)</div>
689       <div class="def">Function SAX:COMMENT (handler data)</div>
690       <div class="def">Function SAX:START-CDATA (handler)</div>
691       <div class="def">Function SAX:END-CDATA (handler)</div>
692       <div class="def">Function SAX:CHARACTERS (handler data)</div>
693       <br/>
694       <div class="def">Function SAX:START-DTD (handler name public-id system-id)</div>
695       <div class="def">Function SAX:END-DTD (handler)</div>
696       <div class="def">Function SAX:START-INTERNAL-SUBSET (handler)</div>
697       <div class="def">Function SAX:END-INTERNAL-SUBSET (handler)</div>
698       <div class="def">Function SAX:UNPARSED-ENTITY-DECLARATION (handler name public-id system-id notation-name)</div>
699       <div class="def">Function SAX:EXTERNAL-ENTITY-DECLARATION (handler kind name public-id system-id)</div>
700       <div class="def">Function SAX:INTERNAL-ENTITY-DECLARATION (handler kind name value)</div>
701       <div class="def">Function SAX:NOTATION-DECLARATION (handler name public-id system-id)</div>
702       <div class="def">Function SAX:ELEMENT-DECLARATION (handler name model)</div>
703       <div class="def">Function SAX:ATTRIBUTE-DECLARATION (handler ename aname type default)</div>
704       <br/>
705       <div class="def">Accessor SAX:ATTRIBUTE-PREFIX (attribute)</div>
706       <div class="def">Accessor SAX:ATTRIBUTE-NAMESPACE-URI (attribute)</div>
707       <div class="def">Accessor SAX:ATTRIBUTE-LOCAL-NAME (attribute)</div>
708       <div class="def">Accessor SAX:ATTRIBUTE-QNAME (attribute)</div>
709       <div class="def">Accessor SAX:ATTRIBUTE-SPECIFIED-P (attribute)</div>
710       <div class="def">Accessor SAX:ATTRIBUTE-VALUE (attribute)</div>
711       <br/>
712       <div class="def">Function SAX:FIND-ATTRIBUTE (qname attributes)</div>
713       <div class="def">Function SAX:FIND-ATTRIBUTE-NS (uri lname attributes)</div>
714     </p>
715     <p>
716       The entity declaration methods are similar to Java SAX
717       definitions, but parameter entities are distinguished from
718       general entities not by a <tt>%</tt> prefix to the name, but by
719       the <tt>kind</tt> argument, either <tt>:parameter</tt> or
720       <tt>:general</tt>.
721     </p>
722     <p>
723       The arguments to <tt>sax:element-declaration</tt> and
724       <tt>sax:attribute-declaration</tt> differ significantly from their
725       Java counterparts.
726     </p>
727     <p>
728       <i>fixme</i>: For more information on these functions refer to the docstrings.
729     </p>
730 </documentation>