1 /*******************************************************************************
2 
3         Copyright: Copyright (C) 2007-2008 Scott Sanders, Kris Bell.  
4                    All rights reserved.
5 
6         License:   BSD style: $(LICENSE)
7 
8         version:   Initial release: February 2008      
9 
10         Authors:   stonecobra, Kris
11 
12         Acknowledgements: 
13                    Many thanks to the entire group that came up with
14                    SAX as an API, and then had the foresight to place
15                    it into the public domain so that it can become a
16                    de-facto standard.  It may not be the best XML API, 
17                    but it sure is handy. For more information, see 
18                    <a href='http://www.saxproject.org'>http://www.saxproject.org</a>.
19 
20 *******************************************************************************/
21 
22 module tango.text.xml.SaxParser;
23 
24 private import tango.io.model.IConduit;
25 private import tango.text.xml.PullParser;
26 
27 /*******************************************************************************
28 
29         Single attributes are represented by this struct.
30 
31  *******************************************************************************/
32 struct Attribute(Ch = char) {
33 
34         const(Ch)[] localName;
35         const(Ch)[] value;
36 
37 }
38 
39 /*******************************************************************************
40  * Receive notification of the logical content of a document.
41  *
42  * <p>This is the main interface that most SAX applications
43  * implement: if the application needs to be informed of basic parsing 
44  * events, it implements this interface and registers an instance with 
45  * the SAX parser using the {@link org.xml.sax.XMLReader#setContentHandler 
46  * setContentHandler} method.  The parser uses the instance to report 
47  * basic document-related events like the start and end of elements 
48  * and character data.</p>
49  *
50  * <p>The order of events in this interface is very important, and
51  * mirrors the order of information in the document itself.  For
52  * example, all of an element's content (character data, processing
53  * instructions, and/or subelements) will appear, in order, between
54  * the startElement event and the corresponding endElement event.</p>
55  *
56  * <p>This interface is similar to the now-deprecated SAX 1.0
57  * DocumentHandler interface, but it adds support for Namespaces
58  * and for reporting skipped entities (in non-validating XML
59  * processors).</p>
60  *
61  * <p>Implementors should note that there is also a 
62  * <code>ContentHandler</code> class in the <code>java.net</code>
63  * package; that means that it's probably a bad idea to do</p>
64  *
65  * <pre>import java.net.*;
66  * import org.xml.sax.*;
67  * </pre>
68  *
69  * <p>In fact, "import ...*" is usually a sign of sloppy programming
70  * anyway, so the user should consider this a feature rather than a
71  * bug.</p>
72  *
73  * @since SAX 2.0
74  * @author David Megginson
75  * @version 2.0.1+ (sax2r3pre1)
76  * @see org.xml.sax.XMLReader
77  * @see org.xml.sax.ErrorHandler
78  *******************************************************************************/
79 public class SaxHandler(Ch = char) {
80         
81         Locator!(Ch) locator;
82 
83         /*******************************************************************************
84          * Receive an object for locating the origin of SAX document events.
85          *
86          * <p>SAX parsers are strongly encouraged (though not absolutely
87          * required) to supply a locator: if it does so, it must supply
88          * the locator to the application by invoking this method before
89          * invoking any of the other methods in the ContentHandler
90          * interface.</p>
91          *
92          * <p>The locator allows the application to determine the end
93          * position of any document-related event, even if the parser is
94          * not reporting an error.  Typically, the application will
95          * use this information for reporting its own errors (such as
96          * character content that does not match an application's
97          * business rules).  The information returned by the locator
98          * is probably not sufficient for use with a search engine.</p>
99          *
100          * <p>Note that the locator will return correct information only
101          * during the invocation SAX event callbacks after
102          * {@link #startDocument startDocument} returns and before
103          * {@link #endDocument endDocument} is called.  The
104          * application should not attempt to use it at any other time.</p>
105          *
106          * @param locator an object that can return the location of
107          *                any SAX document event
108          * @see org.xml.sax.Locator
109          *******************************************************************************/
110         public void setDocumentLocator(Locator!(Ch) locator)
111         {
112                 this.locator = locator;
113         }
114 
115         /*******************************************************************************
116          * Receive notification of the beginning of a document.
117          *
118          * <p>The SAX parser will invoke this method only once, before any
119          * other event callbacks (except for {@link #setDocumentLocator 
120          * setDocumentLocator}).</p>
121          *
122          * @throws org.xml.sax.SAXException any SAX exception, possibly
123          *            wrapping another exception
124          * @see #endDocument
125          *******************************************************************************/
126         public void startDocument()
127         {
128                 
129         }
130 
131         /*******************************************************************************
132          * Receive notification of the end of a document.
133          *
134          * <p><strong>There is an apparent contradiction between the
135          * documentation for this method and the documentation for {@link
136          * org.xml.sax.ErrorHandler#fatalError}.  Until this ambiguity is
137          * resolved in a future major release, clients should make no
138          * assumptions about whether endDocument() will or will not be
139          * invoked when the parser has reported a fatalError() or thrown
140          * an exception.</strong></p>
141          *
142          * <p>The SAX parser will invoke this method only once, and it will
143          * be the last method invoked during the parse.  The parser shall
144          * not invoke this method until it has either abandoned parsing
145          * (because of an unrecoverable error) or reached the end of
146          * input.</p>
147          *
148          * @throws org.xml.sax.SAXException any SAX exception, possibly
149          *            wrapping another exception
150          * @see #startDocument
151          *******************************************************************************/
152         public void endDocument()
153         {
154                 
155         }
156 
157         /*******************************************************************************
158          * Begin the scope of a prefix-URI Namespace mapping.
159          *
160          * <p>The information from this event is not necessary for
161          * normal Namespace processing: the SAX XML reader will 
162          * automatically replace prefixes for element and attribute
163          * names when the <code>http://xml.org/sax/features/namespaces</code>
164          * feature is <var>true</var> (the default).</p>
165          *
166          * <p>There are cases, however, when applications need to
167          * use prefixes in character data or in attribute values,
168          * where they cannot safely be expanded automatically; the
169          * start/endPrefixMapping event supplies the information
170          * to the application to expand prefixes in those contexts
171          * itself, if necessary.</p>
172          *
173          * <p>Note that start/endPrefixMapping events are not
174          * guaranteed to be properly nested relative to each other:
175          * all startPrefixMapping events will occur immediately before the
176          * corresponding {@link #startElement startElement} event, 
177          * and all {@link #endPrefixMapping endPrefixMapping}
178          * events will occur immediately after the corresponding
179          * {@link #endElement endElement} event,
180          * but their order is not otherwise 
181          * guaranteed.</p>
182          *
183          * <p>There should never be start/endPrefixMapping events for the
184          * "xml" prefix, since it is predeclared and immutable.</p>
185          *
186          * @param prefix the Namespace prefix being declared.
187          * An empty string is used for the default element namespace,
188          * which has no prefix.
189          * @param uri the Namespace URI the prefix is mapped to
190          * @throws org.xml.sax.SAXException the client may throw
191          *            an exception during processing
192          * @see #endPrefixMapping
193          * @see #startElement
194          *******************************************************************************/
195         public void startPrefixMapping(const(Ch)[] prefix, const(Ch)[] uri)
196         {
197                 
198         }
199 
200         /*******************************************************************************
201          * End the scope of a prefix-URI mapping.
202          *
203          * <p>See {@link #startPrefixMapping startPrefixMapping} for 
204          * details.  These events will always occur immediately after the
205          * corresponding {@link #endElement endElement} event, but the order of 
206          * {@link #endPrefixMapping endPrefixMapping} events is not otherwise
207          * guaranteed.</p>
208          *
209          * @param prefix the prefix that was being mapped.
210          * This is the empty string when a default mapping scope ends.
211          * @throws org.xml.sax.SAXException the client may throw
212          *            an exception during processing
213          * @see #startPrefixMapping
214          * @see #endElement
215          *******************************************************************************/
216         public void endPrefixMapping(const(Ch)[] prefix)
217         {
218                 
219         }
220 
221         /*******************************************************************************
222          * Receive notification of the beginning of an element.
223          *
224          * <p>The Parser will invoke this method at the beginning of every
225          * element in the XML document; there will be a corresponding
226          * {@link #endElement endElement} event for every startElement event
227          * (even when the element is empty). All of the element's content will be
228          * reported, in order, before the corresponding endElement
229          * event.</p>
230          *
231          * <p>This event allows up to three name components for each
232          * element:</p>
233          *
234          * <ol>
235          * <li>the Namespace URI;</li>
236          * <li>the local name; and</li>
237          * <li>the qualified (prefixed) name.</li>
238          * </ol>
239          *
240          * <p>Any or all of these may be provided, depending on the
241          * values of the <var>http://xml.org/sax/features/namespaces</var>
242          * and the <var>http://xml.org/sax/features/namespace-prefixes</var>
243          * properties:</p>
244          *
245          * <ul>
246          * <li>the Namespace URI and local name are required when 
247          * the namespaces property is <var>true</var> (the default), and are
248          * optional when the namespaces property is <var>false</var> (if one is
249          * specified, both must be);</li>
250          * <li>the qualified name is required when the namespace-prefixes property
251          * is <var>true</var>, and is optional when the namespace-prefixes property
252          * is <var>false</var> (the default).</li>
253          * </ul>
254          *
255          * <p>Note that the attribute list provided will contain only
256          * attributes with explicit values (specified or defaulted):
257          * #IMPLIED attributes will be omitted.  The attribute list
258          * will contain attributes used for Namespace declarations
259          * (xmlns* attributes) only if the
260          * <code>http://xml.org/sax/features/namespace-prefixes</code>
261          * property is true (it is false by default, and support for a 
262          * true value is optional).</p>
263          *
264          * <p>Like {@link #characters characters()}, attribute values may have
265          * characters that need more than one <code>char</code> value.  </p>
266          *
267          * @param uri the Namespace URI, or the empty string if the
268          *        element has no Namespace URI or if Namespace
269          *        processing is not being performed
270          * @param localName the local name (without prefix), or the
271          *        empty string if Namespace processing is not being
272          *        performed
273          * @param qName the qualified name (with prefix), or the
274          *        empty string if qualified names are not available
275          * @param atts the attributes attached to the element.  If
276          *        there are no attributes, it shall be an empty
277          *        Attributes object.  The value of this object after
278          *        startElement returns is undefined
279          * @throws org.xml.sax.SAXException any SAX exception, possibly
280          *            wrapping another exception
281          * @see #endElement
282          * @see org.xml.sax.Attributes
283          * @see org.xml.sax.helpers.AttributesImpl
284          *******************************************************************************/
285         public void startElement(const(Ch)[] uri, const(Ch)[] localName, const(Ch)[] qName, Attribute!(Ch)[] atts)
286         {
287                 
288         }
289 
290         /*******************************************************************************
291          * Receive notification of the end of an element.
292          *
293          * <p>The SAX parser will invoke this method at the end of every
294          * element in the XML document; there will be a corresponding
295          * {@link #startElement startElement} event for every endElement 
296          * event (even when the element is empty).</p>
297          *
298          * <p>For information on the names, see startElement.</p>
299          *
300          * @param uri the Namespace URI, or the empty string if the
301          *        element has no Namespace URI or if Namespace
302          *        processing is not being performed
303          * @param localName the local name (without prefix), or the
304          *        empty string if Namespace processing is not being
305          *        performed
306          * @param qName the qualified XML name (with prefix), or the
307          *        empty string if qualified names are not available
308          * @throws org.xml.sax.SAXException any SAX exception, possibly
309          *            wrapping another exception
310          *******************************************************************************/
311         public void endElement(const(Ch)[] uri, const(Ch)[] localName, const(Ch)[] qName)
312         {
313                 
314         }
315 
316         /*******************************************************************************
317          * Receive notification of character data.
318          *
319          * <p>The Parser will call this method to report each chunk of
320          * character data.  SAX parsers may return all contiguous character
321          * data in a single chunk, or they may split it into several
322          * chunks; however, all of the characters in any single event
323          * must come from the same external entity so that the Locator
324          * provides useful information.</p>
325          *
326          * <p>The application must not attempt to read from the array
327          * outside of the specified range.</p>
328          *
329          * <p>Individual characters may consist of more than one Java
330          * <code>char</code> value.  There are two important cases where this
331          * happens, because characters can't be represented in just sixteen bits.
332          * In one case, characters are represented in a <em>Surrogate Pair</em>,
333          * using two special Unicode values. Such characters are in the so-called
334          * "Astral Planes", with a code point above U+FFFF.  A second case involves
335          * composite characters, such as a base character combining with one or
336          * more accent characters. </p>
337          *
338          * <p> Your code should not assume that algorithms using
339          * <code>char</code>-at-a-time idioms will be working in character
340          * units; in some cases they will split characters.  This is relevant
341          * wherever XML permits arbitrary characters, such as attribute values,
342          * processing instruction data, and comments as well as in data reported
343          * from this method.  It's also generally relevant whenever Java code
344          * manipulates internationalized text; the issue isn't unique to XML.</p>
345          *
346          * <p>Note that some parsers will report whitespace in element
347          * content using the {@link #ignorableWhitespace ignorableWhitespace}
348          * method rather than this one (validating parsers <em>must</em> 
349          * do so).</p>
350          *
351          * @param ch the characters from the XML document
352          * @param start the start position in the array
353          * @param length the number of characters to read from the array
354          * @throws org.xml.sax.SAXException any SAX exception, possibly
355          *            wrapping another exception
356          * @see #ignorableWhitespace 
357          * @see org.xml.sax.Locator
358          *******************************************************************************/
359         public void characters(const(Ch)[] ch)
360         {
361                 
362         }
363 
364         /*******************************************************************************
365          * Receive notification of ignorable whitespace in element content.
366          *
367          * <p>Validating Parsers must use this method to report each chunk
368          * of whitespace in element content (see the W3C XML 1.0
369          * recommendation, section 2.10): non-validating parsers may also
370          * use this method if they are capable of parsing and using
371          * content models.</p>
372          *
373          * <p>SAX parsers may return all contiguous whitespace in a single
374          * chunk, or they may split it into several chunks; however, all of
375          * the characters in any single event must come from the same
376          * external entity, so that the Locator provides useful
377          * information.</p>
378          *
379          * <p>The application must not attempt to read from the array
380          * outside of the specified range.</p>
381          *
382          * @param ch the characters from the XML document
383          * @param start the start position in the array
384          * @param length the number of characters to read from the array
385          * @throws org.xml.sax.SAXException any SAX exception, possibly
386          *            wrapping another exception
387          * @see #characters
388          *******************************************************************************/
389         public void ignorableWhitespace(Ch ch[])
390         {
391                 
392         }
393 
394         /*******************************************************************************
395          * Receive notification of a processing instruction.
396          *
397          * <p>The Parser will invoke this method once for each processing
398          * instruction found: note that processing instructions may occur
399          * before or after the main document element.</p>
400          *
401          * <p>A SAX parser must never report an XML declaration (XML 1.0,
402          * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
403          * using this method.</p>
404          *
405          * <p>Like {@link #characters characters()}, processing instruction
406          * data may have characters that need more than one <code>char</code>
407          * value. </p>
408          *
409          * @param target the processing instruction target
410          * @param data the processing instruction data, or null if
411          *        none was supplied.  The data does not include any
412          *        whitespace separating it from the target
413          * @throws org.xml.sax.SAXException any SAX exception, possibly
414          *            wrapping another exception
415          *******************************************************************************/
416         public void processingInstruction(const(Ch)[] target, const(Ch)[] data)
417         {
418                 
419         }
420 
421         /*******************************************************************************
422          * Receive notification of a skipped entity.
423          * This is not called for entity references within markup constructs
424          * such as element start tags or markup declarations.  (The XML
425          * recommendation requires reporting skipped external entities.
426          * SAX also reports internal entity expansion/non-expansion, except
427          * within markup constructs.)
428          *
429          * <p>The Parser will invoke this method each time the entity is
430          * skipped.  Non-validating processors may skip entities if they
431          * have not seen the declarations (because, for example, the
432          * entity was declared in an external DTD subset).  All processors
433          * may skip external entities, depending on the values of the
434          * <code>http://xml.org/sax/features/external-general-entities</code>
435          * and the
436          * <code>http://xml.org/sax/features/external-parameter-entities</code>
437          * properties.</p>
438          *
439          * @param name the name of the skipped entity.  If it is a 
440          *        parameter entity, the name will begin with '%', and if
441          *        it is the external DTD subset, it will be the string
442          *        "[dtd]"
443          * @throws org.xml.sax.SAXException any SAX exception, possibly
444          *            wrapping another exception
445          *******************************************************************************/
446         public void skippedEntity(const(Ch)[] name)
447         {
448                 
449         }
450 
451 }
452 
453 /*******************************************************************************
454  * Basic interface for resolving entities.
455  *
456  * <p>If a SAX application needs to implement customized handling
457  * for external entities, it must implement this interface and
458  * register an instance with the SAX driver using the
459  * {@link org.xml.sax.XMLReader#setEntityResolver setEntityResolver}
460  * method.</p>
461  *
462  * <p>The XML reader will then allow the application to intercept any
463  * external entities (including the external DTD subset and external
464  * parameter entities, if any) before including them.</p>
465  *
466  * <p>Many SAX applications will not need to implement this interface,
467  * but it will be especially useful for applications that build
468  * XML documents from databases or other specialised input sources,
469  * or for applications that use URI types other than URLs.</p>
470  *
471  * <p>The following resolver would provide the application
472  * with a special character stream for the entity with the system
473  * identifier "http://www.myhost.com/today":</p>
474  *
475  * <pre>
476  * import org.xml.sax.EntityResolver;
477  * import org.xml.sax.InputSource;
478  *
479  * public class MyResolver implements EntityResolver {
480  *   public InputSource resolveEntity (String publicId, String systemId)
481  *   {
482  *     if (systemId.equals("http://www.myhost.com/today")) {
483  *              // return a special input source
484  *       MyReader reader = new MyReader();
485  *       return new InputSource(reader);
486  *     } else {
487  *              // use the default behaviour
488  *       return null;
489  *     }
490  *   }
491  * }
492  * </pre>
493  *
494  * <p>The application can also use this interface to redirect system
495  * identifiers to local URIs or to look up replacements in a catalog
496  * (possibly by using the public identifier).</p>
497  *
498  * @since SAX 1.0
499  * @author David Megginson
500  * @version 2.0.1 (sax2r2)
501  * @see org.xml.sax.XMLReader#setEntityResolver
502  * @see org.xml.sax.InputSource
503  *******************************************************************************/
504 public interface EntityResolver(Ch = char) {
505 
506         /*******************************************************************************
507          * Allow the application to resolve external entities.
508          *
509          * <p>The parser will call this method before opening any external
510          * entity except the top-level document entity.  Such entities include
511          * the external DTD subset and external parameter entities referenced
512          * within the DTD (in either case, only if the parser reads external
513          * parameter entities), and external general entities referenced
514          * within the document element (if the parser reads external general
515          * entities).  The application may request that the parser locate
516          * the entity itself, that it use an alternative URI, or that it
517          * use data provided by the application (as a character or byte
518          * input stream).</p>
519          *
520          * <p>Application writers can use this method to redirect external
521          * system identifiers to secure and/or local URIs, to look up
522          * public identifiers in a catalogue, or to read an entity from a
523          * database or other input source (including, for example, a dialog
524          * box).  Neither XML nor SAX specifies a preferred policy for using
525          * public or system IDs to resolve resources.  However, SAX specifies
526          * how to interpret any InputSource returned by this method, and that
527          * if none is returned, then the system ID will be dereferenced as
528          * a URL.  </p>
529          *
530          * <p>If the system identifier is a URL, the SAX parser must
531          * resolve it fully before reporting it to the application.</p>
532          *
533          * @param publicId The public identifier of the external entity
534          *        being referenced, or null if none was supplied.
535          * @param systemId The system identifier of the external entity
536          *        being referenced.
537          * @return An InputSource object describing the new input source,
538          *         or null to request that the parser open a regular
539          *         URI connection to the system identifier.
540          * @exception org.xml.sax.SAXException Any SAX exception, possibly
541          *            wrapping another exception.
542          * @exception java.io.IOException A Java-specific IO exception,
543          *            possibly the result of creating a new InputStream
544          *            or Reader for the InputSource.
545          * @see org.xml.sax.InputSource
546          *******************************************************************************/
547 
548         public InputStream resolveEntity(const(Ch)[] publicId, const(Ch)[] systemId);
549 
550 }
551 
552 /*******************************************************************************
553  * Basic interface for SAX error handlers.
554  *
555  * <p>If a SAX application needs to implement customized error
556  * handling, it must implement this interface and then register an
557  * instance with the XML reader using the
558  * {@link org.xml.sax.XMLReader#setErrorHandler setErrorHandler}
559  * method.  The parser will then report all errors and warnings
560  * through this interface.</p>
561  *
562  * <p><strong>WARNING:</strong> If an application does <em>not</em>
563  * register an ErrorHandler, XML parsing errors will go unreported,
564  * except that <em>SAXParseException</em>s will be thrown for fatal errors.
565  * In order to detect validity errors, an ErrorHandler that does something
566  * with {@link #error error()} calls must be registered.</p>
567  *
568  * <p>For XML processing errors, a SAX driver must use this interface 
569  * in preference to throwing an exception: it is up to the application 
570  * to decide whether to throw an exception for different types of 
571  * errors and warnings.  Note, however, that there is no requirement that 
572  * the parser continue to report additional errors after a call to 
573  * {@link #fatalError fatalError}.  In other words, a SAX driver class 
574  * may throw an exception after reporting any fatalError.
575  * Also parsers may throw appropriate exceptions for non-XML errors.
576  * For example, {@link XMLReader#parse XMLReader.parse()} would throw
577  * an IOException for errors accessing entities or the document.</p>
578  *
579  * @since SAX 1.0
580  * @author David Megginson
581  * @version 2.0.1+ (sax2r3pre1)
582  * @see org.xml.sax.XMLReader#setErrorHandler
583  * @see org.xml.sax.SAXParseException 
584  *******************************************************************************/
585 public interface ErrorHandler(Ch = char) {
586 
587         /*******************************************************************************
588          * Receive notification of a warning.
589          *
590          * <p>SAX parsers will use this method to report conditions that
591          * are not errors or fatal errors as defined by the XML
592          * recommendation.  The default behaviour is to take no
593          * action.</p>
594          *
595          * <p>The SAX parser must continue to provide normal parsing events
596          * after invoking this method: it should still be possible for the
597          * application to process the document through to the end.</p>
598          *
599          * <p>Filters may use this method to report other, non-XML warnings
600          * as well.</p>
601          *
602          * @param exception The warning information encapsulated in a
603          *                  SAX parse exception.
604          * @exception org.xml.sax.SAXException Any SAX exception, possibly
605          *            wrapping another exception.
606          * @see org.xml.sax.SAXParseException 
607          *******************************************************************************/
608         public void warning(SAXException exception);
609 
610         /*******************************************************************************
611          * Receive notification of a recoverable error.
612          *
613          * <p>This corresponds to the definition of "error" in section 1.2
614          * of the W3C XML 1.0 Recommendation.  For example, a validating
615          * parser would use this callback to report the violation of a
616          * validity constraint.  The default behaviour is to take no
617          * action.</p>
618          *
619          * <p>The SAX parser must continue to provide normal parsing
620          * events after invoking this method: it should still be possible
621          * for the application to process the document through to the end.
622          * If the application cannot do so, then the parser should report
623          * a fatal error even if the XML recommendation does not require
624          * it to do so.</p>
625          *
626          * <p>Filters may use this method to report other, non-XML errors
627          * as well.</p>
628          *
629          * @param exception The error information encapsulated in a
630          *                  SAX parse exception.
631          * @exception org.xml.sax.SAXException Any SAX exception, possibly
632          *            wrapping another exception.
633          * @see org.xml.sax.SAXParseException 
634          *******************************************************************************/
635         public void error(SAXException exception);
636 
637         /*******************************************************************************
638          * Receive notification of a non-recoverable error.
639          *
640          * <p><strong>There is an apparent contradiction between the
641          * documentation for this method and the documentation for {@link
642          * org.xml.sax.ContentHandler#endDocument}.  Until this ambiguity
643          * is resolved in a future major release, clients should make no
644          * assumptions about whether endDocument() will or will not be
645          * invoked when the parser has reported a fatalError() or thrown
646          * an exception.</strong></p>
647          *
648          * <p>This corresponds to the definition of "fatal error" in
649          * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
650          * parser would use this callback to report the violation of a
651          * well-formedness constraint.</p>
652          *
653          * <p>The application must assume that the document is unusable
654          * after the parser has invoked this method, and should continue
655          * (if at all) only for the sake of collecting additional error
656          * messages: in fact, SAX parsers are free to stop reporting any
657          * other events once this method has been invoked.</p>
658          *
659          * @param exception The error information encapsulated in a
660          *                  SAX parse exception.  
661          * @exception org.xml.sax.SAXException Any SAX exception, possibly
662          *            wrapping another exception.
663          * @see org.xml.sax.SAXParseException
664          *******************************************************************************/
665         public void fatalError(SAXException exception);
666 
667 }
668 
669 /*******************************************************************************
670  * Interface for associating a SAX event with a document location.
671  *
672  * <p>If a SAX parser provides location information to the SAX
673  * application, it does so by implementing this interface and then
674  * passing an instance to the application using the content
675  * handler's {@link org.xml.sax.ContentHandler#setDocumentLocator
676  * setDocumentLocator} method.  The application can use the
677  * object to obtain the location of any other SAX event
678  * in the XML source document.</p>
679  *
680  * <p>Note that the results returned by the object will be valid only
681  * during the scope of each callback method: the application
682  * will receive unpredictable results if it attempts to use the
683  * locator at any other time, or after parsing completes.</p>
684  *
685  * <p>SAX parsers are not required to supply a locator, but they are
686  * very strongly encouraged to do so.  If the parser supplies a
687  * locator, it must do so before reporting any other document events.
688  * If no locator has been set by the time the application receives
689  * the {@link org.xml.sax.ContentHandler#startDocument startDocument}
690  * event, the application should assume that a locator is not 
691  * available.</p>
692  *
693  * @since SAX 1.0
694  * @author David Megginson
695  * @version 2.0.1 (sax2r2)
696  * @see org.xml.sax.ContentHandler#setDocumentLocator 
697  *******************************************************************************/
698 public interface Locator(Ch = char) {
699 
700         /*******************************************************************************
701          * Return the public identifier for the current document event.
702          *
703          * <p>The return value is the public identifier of the document
704          * entity or of the external parsed entity in which the markup
705          * triggering the event appears.</p>
706          *
707          * @return A string containing the public identifier, or
708          *         null if none is available.
709          * @see #getSystemId
710          *******************************************************************************/
711         public const(Ch)[] getPublicId();
712 
713         /*******************************************************************************
714          * Return the system identifier for the current document event.
715          *
716          * <p>The return value is the system identifier of the document
717          * entity or of the external parsed entity in which the markup
718          * triggering the event appears.</p>
719          *
720          * <p>If the system identifier is a URL, the parser must resolve it
721          * fully before passing it to the application.  For example, a file
722          * name must always be provided as a <em>file:...</em> URL, and other
723          * kinds of relative URI are also resolved against their bases.</p>
724          *
725          * @return A string containing the system identifier, or null
726          *         if none is available.
727          * @see #getPublicId
728          *******************************************************************************/
729         public const(Ch)[] getSystemId();
730 
731         /*******************************************************************************
732          * Return the line number where the current document event ends.
733          * Lines are delimited by line ends, which are defined in
734          * the XML specification.
735          *
736          * <p><strong>Warning:</strong> The return value from the method
737          * is intended only as an approximation for the sake of diagnostics;
738          * it is not intended to provide sufficient information
739          * to edit the character content of the original XML document.
740          * In some cases, these "line" numbers match what would be displayed
741          * as columns, and in others they may not match the source text
742          * due to internal entity expansion.  </p>
743          *
744          * <p>The return value is an approximation of the line number
745          * in the document entity or external parsed entity where the
746          * markup triggering the event appears.</p>
747          *
748          * <p>If possible, the SAX driver should provide the line position 
749          * of the first character after the text associated with the document 
750          * event.  The first line is line 1.</p>
751          *
752          * @return The line number, or -1 if none is available.
753          * @see #getColumnNumber
754          *******************************************************************************/
755         public int getLineNumber();
756 
757         /*******************************************************************************
758          * Return the column number where the current document event ends.
759          * This is one-based number of Java <code>char</code> values since
760          * the last line end.
761          *
762          * <p><strong>Warning:</strong> The return value from the method
763          * is intended only as an approximation for the sake of diagnostics;
764          * it is not intended to provide sufficient information
765          * to edit the character content of the original XML document.
766          * For example, when lines contain combining character sequences, wide
767          * characters, surrogate pairs, or bi-directional text, the value may
768          * not correspond to the column in a text editor's display. </p>
769          *
770          * <p>The return value is an approximation of the column number
771          * in the document entity or external parsed entity where the
772          * markup triggering the event appears.</p>
773          *
774          * <p>If possible, the SAX driver should provide the line position 
775          * of the first character after the text associated with the document 
776          * event.  The first column in each line is column 1.</p>
777          *
778          * @return The column number, or -1 if none is available.
779          * @see #getLineNumber
780          *******************************************************************************/
781         public int getColumnNumber();
782 
783 }
784 
785 
786 /*******************************************************************************
787  * Encapsulate a general SAX error or warning.
788  *
789  * <p>This class can contain basic error or warning information from
790  * either the XML parser or the application: a parser writer or
791  * application writer can subclass it to provide additional
792  * functionality.  SAX handlers may throw this exception or
793  * any exception subclassed from it.</p>
794  *
795  * <p>If the application needs to pass through other types of
796  * exceptions, it must wrap those exceptions in a SAXException
797  * or an exception derived from a SAXException.</p>
798  *
799  * <p>If the parser or application needs to include information about a
800  * specific location in an XML document, it should use the
801  * {@link org.xml.sax.SAXParseException SAXParseException} subclass.</p>
802  *
803  * @since SAX 1.0
804  * @author David Megginson
805  * @version 2.0.1 (sax2r2)
806  * @see org.xml.sax.SAXParseException
807  *******************************************************************************/
808 public class SAXException : Exception {
809 
810         /*******************************************************************************
811          * Create a new SAXException.
812          *******************************************************************************/
813         public this () {
814                 super ("", cast(Throwable)null);
815         }
816 
817         /*******************************************************************************
818          * Create a new SAXException.
819          *
820          * @param message The error or warning message.
821          *******************************************************************************/
822         public this (immutable(char)[] message) {
823                 super (message, cast(Throwable)null);
824         }
825 
826         /*******************************************************************************
827          * Create a new SAXException wrapping an existing exception.
828          *
829          * <p>The existing exception will be embedded in the new
830          * one, and its message will become the default message for
831          * the SAXException.</p>
832          *
833          * @param e The exception to be wrapped in a SAXException.
834          *******************************************************************************/
835         public this (Exception e) {
836                 super ("", e);
837         }
838 
839         /*******************************************************************************
840          * Create a new SAXException from an existing exception.
841          *
842          * <p>The existing exception will be embedded in the new
843          * one, but the new exception will have its own message.</p>
844          *
845          * @param message The detail message.
846          * @param e The exception to be wrapped in a SAXException.
847          *******************************************************************************/
848         public this (immutable(char)[] message, Exception e) {
849                 super (message, e);
850         }
851 
852         /*******************************************************************************
853          * Return a detail message for this exception.
854          *
855          * <p>If there is an embedded exception, and if the SAXException
856          * has no detail message of its own, this method will return
857          * the detail message from the embedded exception.</p>
858          *
859          * @return The error or warning message.
860          *******************************************************************************/
861         public immutable(char)[] message() {
862                 if (msg is null && next !is null) {
863                         return next.msg;
864                 }
865                 else {
866                         return msg;
867                 }
868 
869         }
870 
871 }
872 /*******************************************************************************
873  *******************************************************************************/
874 class SaxParser(Ch = char) : XMLReader!(Ch), Locator!(Ch) {
875 
876         private SaxHandler!(Ch) saxHandler;
877         private ErrorHandler!(Ch) errorHandler;
878         private EntityResolver!(Ch) entityResolver;
879         private const(Ch)[] content;
880         private Attribute!(Ch)[] attributes;
881         private int attrTop = 0;
882         private bool hasStartElement = false;
883         private const(Ch)[] startElemName;
884         private PullParser!(Ch) parser;
885 
886         /*******************************************************************************
887          *******************************************************************************/
888         public this() {
889                 attributes = new Attribute!(Ch)[255];
890         }
891 
892         ////////////////////////////////////////////////////////////////////
893         // Configuration.
894         ////////////////////////////////////////////////////////////////////
895         /*******************************************************************************
896          * Look up the value of a feature flag.
897          *
898          * <p>The feature name is any fully-qualified URI.  It is
899          * possible for an XMLReader to recognize a feature name but
900          * temporarily be unable to return its value.
901          * Some feature values may be available only in specific
902          * contexts, such as before, during, or after a parse.
903          * Also, some feature values may not be programmatically accessible.
904          * (In the case of an adapter for SAX1 {@link Parser}, there is no
905          * implementation-independent way to expose whether the underlying
906          * parser is performing validation, expanding external entities,
907          * and so forth.) </p>
908          *
909          * <p>All XMLReaders are required to recognize the
910          * http://xml.org/sax/features/namespaces and the
911          * http://xml.org/sax/features/namespace-prefixes feature names.</p>
912          *
913          * <p>Typical usage is something like this:</p>
914          *
915          * <pre>
916          * XMLReader r = new MySAXDriver();
917          *
918          *                         // try to activate validation
919          * try {
920          *   r.setFeature("http://xml.org/sax/features/validation", true);
921          * } catch (SAXException e) {
922          *   System.err.println("Cannot activate validation."); 
923          * }
924          *
925          *                         // register event handlers
926          * r.setContentHandler(new MyContentHandler());
927          * r.setErrorHandler(new MyErrorHandler());
928          *
929          *                         // parse the first document
930          * try {
931          *   r.parse("http://www.foo.com/mydoc.xml");
932          * } catch (IOException e) {
933          *   System.err.println("I/O exception reading XML document");
934          * } catch (SAXException e) {
935          *   System.err.println("XML exception reading document.");
936          * }
937          * </pre>
938          *
939          * <p>Implementors are free (and encouraged) to invent their own features,
940          * using names built on their own URIs.</p>
941          *
942          * @param name The feature name, which is a fully-qualified URI.
943          * @return The current value of the feature (true or false).
944          * @exception org.xml.sax.SAXNotRecognizedException If the feature
945          *            value can't be assigned or retrieved.
946          * @exception org.xml.sax.SAXNotSupportedException When the
947          *            XMLReader recognizes the feature name but 
948          *            cannot determine its value at this time.
949          * @see #setFeature
950          *******************************************************************************/
951         public bool getFeature(const(Ch)[] name) {
952                 return false;
953         }
954 
955         /*******************************************************************************
956          * Set the value of a feature flag.
957          *
958          * <p>The feature name is any fully-qualified URI.  It is
959          * possible for an XMLReader to expose a feature value but
960          * to be unable to change the current value.
961          * Some feature values may be immutable or mutable only 
962          * in specific contexts, such as before, during, or after 
963          * a parse.</p>
964          *
965          * <p>All XMLReaders are required to support setting
966          * http://xml.org/sax/features/namespaces to true and
967          * http://xml.org/sax/features/namespace-prefixes to false.</p>
968          *
969          * @param name The feature name, which is a fully-qualified URI.
970          * @param value The requested value of the feature (true or false).
971          * @exception org.xml.sax.SAXNotRecognizedException If the feature
972          *            value can't be assigned or retrieved.
973          * @exception org.xml.sax.SAXNotSupportedException When the
974          *            XMLReader recognizes the feature name but 
975          *            cannot set the requested value.
976          * @see #getFeature
977          *******************************************************************************/
978         public void setFeature(const(Ch)[] name, bool value) {
979 
980         }
981 
982         /*******************************************************************************
983          * Look up the value of a property.
984          *
985          * <p>The property name is any fully-qualified URI.  It is
986          * possible for an XMLReader to recognize a property name but
987          * temporarily be unable to return its value.
988          * Some property values may be available only in specific
989          * contexts, such as before, during, or after a parse.</p>
990          *
991          * <p>XMLReaders are not required to recognize any specific
992          * property names, though an initial core set is documented for
993          * SAX2.</p>
994          *
995          * <p>Implementors are free (and encouraged) to invent their own properties,
996          * using names built on their own URIs.</p>
997          *
998          * @param name The property name, which is a fully-qualified URI.
999          * @return The current value of the property.
1000          * @exception org.xml.sax.SAXNotRecognizedException If the property
1001          *            value can't be assigned or retrieved.
1002          * @exception org.xml.sax.SAXNotSupportedException When the
1003          *            XMLReader recognizes the property name but 
1004          *            cannot determine its value at this time.
1005          * @see #setProperty
1006          *******************************************************************************/
1007         public Object getProperty(const(Ch)[] name) {
1008                 return null;
1009         }
1010 
1011         /*******************************************************************************
1012          * Set the value of a property.
1013          *
1014          * <p>The property name is any fully-qualified URI.  It is
1015          * possible for an XMLReader to recognize a property name but
1016          * to be unable to change the current value.
1017          * Some property values may be immutable or mutable only 
1018          * in specific contexts, such as before, during, or after 
1019          * a parse.</p>
1020          *
1021          * <p>XMLReaders are not required to recognize setting
1022          * any specific property names, though a core set is defined by 
1023          * SAX2.</p>
1024          *
1025          * <p>This method is also the standard mechanism for setting
1026          * extended handlers.</p>
1027          *
1028          * @param name The property name, which is a fully-qualified URI.
1029          * @param value The requested value for the property.
1030          * @exception org.xml.sax.SAXNotRecognizedException If the property
1031          *            value can't be assigned or retrieved.
1032          * @exception org.xml.sax.SAXNotSupportedException When the
1033          *            XMLReader recognizes the property name but 
1034          *            cannot set the requested value.
1035          *******************************************************************************/
1036         public void setProperty(const(Ch)[] name, Object value) {
1037 
1038         }
1039 
1040         ////////////////////////////////////////////////////////////////////
1041         // Event handlers.
1042         ////////////////////////////////////////////////////////////////////
1043         /*******************************************************************************
1044          * Allow an application to register an entity resolver.
1045          *
1046          * <p>If the application does not register an entity resolver,
1047          * the XMLReader will perform its own default resolution.</p>
1048          *
1049          * <p>Applications may register a new or different resolver in the
1050          * middle of a parse, and the SAX parser must begin using the new
1051          * resolver immediately.</p>
1052          *
1053          * @param resolver The entity resolver.
1054          * @see #getEntityResolver
1055          *******************************************************************************/
1056         public void setEntityResolver(EntityResolver!(Ch) resolver) {
1057                 entityResolver = resolver;
1058         }
1059 
1060         /*******************************************************************************
1061          * Return the current entity resolver.
1062          *
1063          * @return The current entity resolver, or null if none
1064          *         has been registered.
1065          * @see #setEntityResolver
1066          *******************************************************************************/
1067         public EntityResolver!(Ch) getEntityResolver() {
1068                 return entityResolver;
1069         }
1070 
1071         /*******************************************************************************
1072          * Allow an application to register a content event handler.
1073          *
1074          * <p>If the application does not register a content handler, all
1075          * content events reported by the SAX parser will be silently
1076          * ignored.</p>
1077          *
1078          * <p>Applications may register a new or different handler in the
1079          * middle of a parse, and the SAX parser must begin using the new
1080          * handler immediately.</p>
1081          *
1082          * @param handler The content handler.
1083          * @see #getContentHandler
1084          *******************************************************************************/
1085         public void setSaxHandler(SaxHandler!(Ch) handler) {
1086                 saxHandler = handler;
1087         }
1088 
1089         /*******************************************************************************
1090          * Return the current content handler.
1091          *
1092          * @return The current content handler, or null if none
1093          *         has been registered.
1094          * @see #setContentHandler
1095          *******************************************************************************/
1096         public SaxHandler!(Ch) getSaxHandler() {
1097                 return saxHandler;
1098         }
1099 
1100         /*******************************************************************************
1101          * Allow an application to register an error event handler.
1102          *
1103          * <p>If the application does not register an error handler, all
1104          * error events reported by the SAX parser will be silently
1105          * ignored; however, normal processing may not continue.  It is
1106          * highly recommended that all SAX applications implement an
1107          * error handler to avoid unexpected bugs.</p>
1108          *
1109          * <p>Applications may register a new or different handler in the
1110          * middle of a parse, and the SAX parser must begin using the new
1111          * handler immediately.</p>
1112          *
1113          * @param handler The error handler.
1114          * @see #getErrorHandler
1115          *******************************************************************************/
1116         public void setErrorHandler(ErrorHandler!(Ch) handler) {
1117                 errorHandler = handler;
1118         }
1119 
1120         /*******************************************************************************
1121          * Return the current error handler.
1122          *
1123          * @return The current error handler, or null if none
1124          *         has been registered.
1125          * @see #setErrorHandler
1126          *******************************************************************************/
1127         public ErrorHandler!(Ch) getErrorHandler() {
1128                 return errorHandler;
1129         }
1130 
1131         ////////////////////////////////////////////////////////////////////
1132         // Parsing.
1133         ////////////////////////////////////////////////////////////////////
1134         /*******************************************************************************
1135          * Parse an XML document.
1136          *
1137          * <p>The application can use this method to instruct the XML
1138          * reader to begin parsing an XML document from any valid input
1139          * source (a character stream, a byte stream, or a URI).</p>
1140          *
1141          * <p>Applications may not invoke this method while a parse is in
1142          * progress (they should create a new XMLReader instead for each
1143          * nested XML document).  Once a parse is complete, an
1144          * application may reuse the same XMLReader object, possibly with a
1145          * different input source.
1146          * Configuration of the XMLReader object (such as handler bindings and
1147          * values established for feature flags and properties) is unchanged
1148          * by completion of a parse, unless the definition of that aspect of
1149          * the configuration explicitly specifies other behavior.
1150          * (For example, feature flags or properties exposing
1151          * characteristics of the document being parsed.)
1152          * </p>
1153          *
1154          * <p>During the parse, the XMLReader will provide information
1155          * about the XML document through the registered event
1156          * handlers.</p>
1157          *
1158          * <p>This method is synchronous: it will not return until parsing
1159          * has ended.  If a client application wants to terminate 
1160          * parsing early, it should throw an exception.</p>
1161          *
1162          * @param input The input source for the top-level of the
1163          *        XML document.
1164          * @exception org.xml.sax.SAXException Any SAX exception, possibly
1165          *            wrapping another exception.
1166          * @exception java.io.IOException An IO exception from the parser,
1167          *            possibly from a byte stream or character stream
1168          *            supplied by the application.
1169          * @see org.xml.sax.InputSource
1170          * @see #parse(java.lang.String)
1171          * @see #setEntityResolver
1172          * @see #setContentHandler
1173          * @see #setErrorHandler 
1174          *******************************************************************************/
1175         private void parse(InputStream input) {
1176                 //TODO turn into a const(Ch)[] buffer
1177                 doParse();
1178         }
1179 
1180         /*******************************************************************************
1181          * Parse an XML document from a system identifier (URI).
1182          *
1183          * <p>This method is a shortcut for the common case of reading a
1184          * document from a system identifier.  It is the exact
1185          * equivalent of the following:</p>
1186          *
1187          * <pre>
1188          * parse(new InputSource(systemId));
1189          * </pre>
1190          *
1191          * <p>If the system identifier is a URL, it must be fully resolved
1192          * by the application before it is passed to the parser.</p>
1193          *
1194          * @param systemId The system identifier (URI).
1195          * @exception org.xml.sax.SAXException Any SAX exception, possibly
1196          *            wrapping another exception.
1197          * @exception java.io.IOException An IO exception from the parser,
1198          *            possibly from a byte stream or character stream
1199          *            supplied by the application.
1200          * @see #parse(org.xml.sax.InputSource)
1201          *******************************************************************************/
1202         private void parseUrl(const(Ch)[] systemId) {
1203                 //TODO turn url into a const(Ch)[] buffer
1204                 doParse();
1205         }
1206 
1207         /*******************************************************************************
1208          * Parse an XML document from a character array.
1209          *
1210          * @param content The actual document content.
1211          * @exception org.xml.sax.SAXException Any SAX exception, possibly
1212          *            wrapping another exception.
1213          * @exception java.io.IOException An IO exception from the parser,
1214          *            possibly from a byte stream or character stream
1215          *            supplied by the application.
1216          * @see #parse(org.xml.sax.InputSource)
1217          *******************************************************************************/
1218         public void parse(const(Ch)[] content) {
1219 	        this.setContent(content);
1220                 doParse();
1221         }
1222 
1223         /*******************************************************************************
1224          *******************************************************************************/
1225         public void parse() {
1226                 doParse();
1227         }
1228 
1229         /*******************************************************************************
1230          *******************************************************************************/
1231         public void setContent(const(Ch)[] content) {
1232 	        if (!parser) {
1233                         parser = new PullParser!(Ch)(content);
1234 		} else {
1235 		        parser.reset(content);
1236 		}
1237         }
1238 
1239         /*******************************************************************************
1240          *******************************************************************************/
1241         public void reset() {
1242                 parser.reset();
1243         }
1244 
1245         /*******************************************************************************
1246          *         The meat of the class.  Turn the pull parser's nodes into SAX
1247          *         events and send out to the SaxHandler.
1248          *******************************************************************************/
1249         private void doParse() {
1250                 saxHandler.setDocumentLocator(this);
1251                 saxHandler.startDocument();
1252                 while (true) {
1253                         switch (parser.next) {
1254                         case XmlTokenType.StartElement :
1255                                 if (hasStartElement) {
1256                                         saxHandler.startElement(null, startElemName, null, attributes[0..attrTop]);
1257                                         hasStartElement = false;
1258                                         attrTop = 0;
1259                                 }               
1260                                 startElemName = parser.localName;
1261                                 hasStartElement = true;
1262                                 break;
1263                         case XmlTokenType.Attribute :
1264                                 attributes[attrTop].localName = parser.localName;
1265                                 attributes[attrTop].value = parser.rawValue;
1266                                 attrTop++;
1267                                 break;
1268                         case XmlTokenType.EndElement :
1269                         case XmlTokenType.EndEmptyElement :
1270                                 if (hasStartElement) {
1271                                         saxHandler.startElement(null, startElemName, null, attributes[0..attrTop]);
1272                                         hasStartElement = false;
1273                                         attrTop = 0;
1274                                 }               
1275                                 saxHandler.endElement(null, parser.localName, null);
1276                                 break;
1277                         case XmlTokenType.Data :
1278                                 if (hasStartElement) {
1279                                         saxHandler.startElement(null, startElemName, null, attributes[0..attrTop]);
1280                                         hasStartElement = false;
1281                                         attrTop = 0;
1282                                 }               
1283                                 saxHandler.characters(parser.rawValue);
1284                                 break;
1285                         case XmlTokenType.Comment :
1286                         case XmlTokenType.CData :
1287                         case XmlTokenType.Doctype :
1288                         case XmlTokenType.PI :
1289                         case XmlTokenType.None :
1290                                 if (hasStartElement) {
1291                                         saxHandler.startElement(null, startElemName, null, attributes[0..attrTop]);
1292                                         hasStartElement = false;
1293                                         attrTop = 0;
1294                                 }               
1295                                 break;
1296 
1297                         case XmlTokenType.Done:
1298                              goto foo;
1299 
1300                         default:
1301                                 throw new SAXException("unknown parser token type");
1302                         }
1303                 } 
1304 foo:                              
1305                 saxHandler.endDocument();
1306         }
1307 
1308         /*******************************************************************************
1309          * Return the public identifier for the current document event.
1310          *
1311          * <p>The return value is the public identifier of the document
1312          * entity or of the external parsed entity in which the markup
1313          * triggering the event appears.</p>
1314          *
1315          * @return A string containing the public identifier, or
1316          *         null if none is available.
1317          * @see #getSystemId
1318          *******************************************************************************/
1319         public const(Ch)[] getPublicId() {
1320                 return null;
1321         }
1322 
1323         /*******************************************************************************
1324          * Return the system identifier for the current document event.
1325          *
1326          * <p>The return value is the system identifier of the document
1327          * entity or of the external parsed entity in which the markup
1328          * triggering the event appears.</p>
1329          *
1330          * <p>If the system identifier is a URL, the parser must resolve it
1331          * fully before passing it to the application.  For example, a file
1332          * name must always be provided as a <em>file:...</em> URL, and other
1333          * kinds of relative URI are also resolved against their bases.</p>
1334          *
1335          * @return A string containing the system identifier, or null
1336          *         if none is available.
1337          * @see #getPublicId
1338          *******************************************************************************/
1339         public const(Ch)[] getSystemId() {
1340                 return null;  
1341         }
1342 
1343         /*******************************************************************************
1344          * Return the line number where the current document event ends.
1345          * Lines are delimited by line ends, which are defined in
1346          * the XML specification.
1347          *
1348          * <p><strong>Warning:</strong> The return value from the method
1349          * is intended only as an approximation for the sake of diagnostics;
1350          * it is not intended to provide sufficient information
1351          * to edit the character content of the original XML document.
1352          * In some cases, these "line" numbers match what would be displayed
1353          * as columns, and in others they may not match the source text
1354          * due to internal entity expansion.  </p>
1355          *
1356          * <p>The return value is an approximation of the line number
1357          * in the document entity or external parsed entity where the
1358          * markup triggering the event appears.</p>
1359          *
1360          * <p>If possible, the SAX driver should provide the line position 
1361          * of the first character after the text associated with the document 
1362          * event.  The first line is line 1.</p>
1363          *
1364          * @return The line number, or -1 if none is available.
1365          * @see #getColumnNumber
1366          *******************************************************************************/
1367         public int getLineNumber() {
1368                 return 0;
1369         }
1370 
1371         /*******************************************************************************
1372          * Return the column number where the current document event ends.
1373          * This is one-based number of Java <code>char</code> values since
1374          * the last line end.
1375          *
1376          * <p><strong>Warning:</strong> The return value from the method
1377          * is intended only as an approximation for the sake of diagnostics;
1378          * it is not intended to provide sufficient information
1379          * to edit the character content of the original XML document.
1380          * For example, when lines contain combining character sequences, wide
1381          * characters, surrogate pairs, or bi-directional text, the value may
1382          * not correspond to the column in a text editor's display. </p>
1383          *
1384          * <p>The return value is an approximation of the column number
1385          * in the document entity or external parsed entity where the
1386          * markup triggering the event appears.</p>
1387          *
1388          * <p>If possible, the SAX driver should provide the line position 
1389          * of the first character after the text associated with the document 
1390          * event.  The first column in each line is column 1.</p>
1391          *
1392          * @return The column number, or -1 if none is available.
1393          * @see #getLineNumber
1394          *******************************************************************************/
1395         public int getColumnNumber() {
1396                 return 0;
1397         }
1398 
1399 
1400 }
1401 
1402 
1403 /*******************************************************************************
1404  * Interface for an XML filter.
1405  *
1406  * <p>An XML filter is like an XML reader, except that it obtains its
1407  * events from another XML reader rather than a primary source like
1408  * an XML document or database.  Filters can modify a stream of
1409  * events as they pass on to the final application.</p>
1410  *
1411  * <p>The XMLFilterImpl helper class provides a convenient base
1412  * for creating SAX2 filters, by passing on all {@link org.xml.sax.EntityResolver
1413  * EntityResolver}, {@link org.xml.sax.DTDHandler DTDHandler},
1414  * {@link org.xml.sax.ContentHandler ContentHandler} and {@link org.xml.sax.ErrorHandler
1415  * ErrorHandler} events automatically.</p>
1416  *
1417  * @since SAX 2.0
1418  * @author David Megginson
1419  * @version 2.0.1 (sax2r2)
1420  * @see org.xml.sax.helpers.XMLFilterImpl
1421  *******************************************************************************/
1422 public abstract class XMLFilter(Ch = char) : XMLReader {
1423 
1424         /*******************************************************************************
1425          * Set the parent reader.
1426          *
1427          * <p>This method allows the application to link the filter to
1428          * a parent reader (which may be another filter).  The argument
1429          * may not be null.</p>
1430          *
1431          * @param parent The parent reader.
1432          *******************************************************************************/
1433         public void setParent(XMLReader parent){
1434                 //do nothing
1435         }
1436 
1437         /*******************************************************************************
1438          * Get the parent reader.
1439          *
1440          * <p>This method allows the application to query the parent
1441          * reader (which may be another filter).  It is generally a
1442          * bad idea to perform any operations on the parent reader
1443          * directly: they should all pass through this filter.</p>
1444          *
1445          * @return The parent filter, or null if none has been set.
1446          *******************************************************************************/
1447         public XMLReader getParent() {
1448                 return null;
1449         }
1450 
1451 }
1452 
1453 /*******************************************************************************
1454  * Base class for deriving an XML filter.
1455  *
1456  * <p>This class is designed to sit between an {@link org.xml.sax.XMLReader
1457  * XMLReader} and the client application's event handlers.  By default, it
1458  * does nothing but pass requests up to the reader and events
1459  * on to the handlers unmodified, but subclasses can override
1460  * specific methods to modify the event stream or the configuration
1461  * requests as they pass through.</p>
1462  *
1463  * @since SAX 2.0
1464  * @author David Megginson
1465  * @version 2.0.1 (sax2r2)
1466  * @see org.xml.sax.XMLFilter
1467  * @see org.xml.sax.XMLReader
1468  * @see org.xml.sax.EntityResolver
1469  * @see org.xml.sax.ContentHandler
1470  * @see org.xml.sax.ErrorHandler
1471  *******************************************************************************/
1472 public class XMLFilterImpl(Ch = char) : SaxHandler, XMLFilter, EntityResolver, ErrorHandler {
1473 
1474         ////////////////////////////////////////////////////////////////////
1475         // Constructors.
1476         ////////////////////////////////////////////////////////////////////
1477         /*******************************************************************************
1478          * Construct an empty XML filter, with no parent.
1479          *
1480          * <p>This filter will have no parent: you must assign a parent
1481          * before you start a parse or do any configuration with
1482          * setFeature or setProperty, unless you use this as a pure event
1483          * consumer rather than as an {@link XMLReader}.</p>
1484          *
1485          * @see org.xml.sax.XMLReader#setFeature
1486          * @see org.xml.sax.XMLReader#setProperty
1487          * @see #setParent
1488          *******************************************************************************/
1489         public this () {
1490 
1491         }
1492 
1493         /*******************************************************************************
1494          * Construct an XML filter with the specified parent.
1495          *
1496          * @see #setParent
1497          * @see #getParent
1498          *******************************************************************************/
1499         public this (XMLReader parent) {
1500                 setParent(parent);
1501         }
1502 
1503         ////////////////////////////////////////////////////////////////////
1504         // Implementation of org.xml.sax.XMLFilter.
1505         ////////////////////////////////////////////////////////////////////
1506         /*******************************************************************************
1507          * Set the parent reader.
1508          *
1509          * <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which 
1510          * this filter will obtain its events and to which it will pass its 
1511          * configuration requests.  The parent may itself be another filter.</p>
1512          *
1513          * <p>If there is no parent reader set, any attempt to parse
1514          * or to set or get a feature or property will fail.</p>
1515          *
1516          * @param parent The parent XML reader.
1517          * @see #getParent
1518          *******************************************************************************/
1519         public void setParent(XMLReader parent) {
1520                 this.parent = parent;
1521         }
1522 
1523         /*******************************************************************************
1524          * Get the parent reader.
1525          *
1526          * @return The parent XML reader, or null if none is set.
1527          * @see #setParent
1528          *******************************************************************************/
1529         public XMLReader getParent() {
1530                 return parent;
1531         }
1532 
1533         ////////////////////////////////////////////////////////////////////
1534         // Implementation of org.xml.sax.XMLReader.
1535         ////////////////////////////////////////////////////////////////////
1536         /*******************************************************************************
1537          * Set the value of a feature.
1538          *
1539          * <p>This will always fail if the parent is null.</p>
1540          *
1541          * @param name The feature name.
1542          * @param value The requested feature value.
1543          * @exception org.xml.sax.SAXNotRecognizedException If the feature
1544          *            value can't be assigned or retrieved from the parent.
1545          * @exception org.xml.sax.SAXNotSupportedException When the
1546          *            parent recognizes the feature name but 
1547          *            cannot set the requested value.
1548          *******************************************************************************/
1549         public void setFeature(const(Ch)[] name, bool value) {
1550                 if (parent !is null) {
1551                         parent.setFeature(name, value);
1552                 }
1553                 else {
1554                         throw new SAXException("Feature not recognized: " ~ name);
1555                 }
1556 
1557         }
1558 
1559         /*******************************************************************************
1560          * Look up the value of a feature.
1561          *
1562          * <p>This will always fail if the parent is null.</p>
1563          *
1564          * @param name The feature name.
1565          * @return The current value of the feature.
1566          * @exception org.xml.sax.SAXNotRecognizedException If the feature
1567          *            value can't be assigned or retrieved from the parent.
1568          * @exception org.xml.sax.SAXNotSupportedException When the
1569          *            parent recognizes the feature name but 
1570          *            cannot determine its value at this time.
1571          *******************************************************************************/
1572         public bool getFeature(const(Ch)[] name) {
1573                 if (parent !is null) {
1574                         return parent.getFeature(name);
1575                 }
1576                 else {
1577                         throw new SAXException("Feature not recognized: " ~ name);
1578                 }
1579 
1580         }
1581 
1582         /*******************************************************************************
1583          * Set the value of a property.
1584          *
1585          * <p>This will always fail if the parent is null.</p>
1586          *
1587          * @param name The property name.
1588          * @param value The requested property value.
1589          * @exception org.xml.sax.SAXNotRecognizedException If the property
1590          *            value can't be assigned or retrieved from the parent.
1591          * @exception org.xml.sax.SAXNotSupportedException When the
1592          *            parent recognizes the property name but 
1593          *            cannot set the requested value.
1594          *******************************************************************************/
1595         public void setProperty(const(Ch)[] name, Object value) {
1596                 if (parent !is null) {
1597                         parent.setProperty(name, value);
1598                 }
1599                 else {
1600                         throw new SAXException("Property not recognized: " ~ name);
1601                 }
1602 
1603         }
1604 
1605         /*******************************************************************************
1606          * Look up the value of a property.
1607          *
1608          * @param name The property name.
1609          * @return The current value of the property.
1610          * @exception org.xml.sax.SAXNotRecognizedException If the property
1611          *            value can't be assigned or retrieved from the parent.
1612          * @exception org.xml.sax.SAXNotSupportedException When the
1613          *            parent recognizes the property name but 
1614          *            cannot determine its value at this time.
1615          *******************************************************************************/
1616         public Object getProperty(const(Ch)[] name) {
1617                 if (parent !is null) {
1618                         return parent.getProperty(name);
1619                 }
1620                 else {
1621                         throw new SAXException("Property not recognized: " ~ name);
1622                 }
1623 
1624         }
1625 
1626         /*******************************************************************************
1627          * Set the entity resolver.
1628          *
1629          * @param resolver The new entity resolver.
1630          *******************************************************************************/
1631         public void setEntityResolver(EntityResolver resolver) {
1632                 entityResolver = resolver;
1633         }
1634 
1635         /**
1636          * Get the current entity resolver.
1637          *
1638          * @return The current entity resolver, or null if none was set.
1639          *******************************************************************************/
1640         public EntityResolver getEntityResolver() {
1641                 return entityResolver;
1642         }
1643 
1644         /*******************************************************************************
1645          * Set the content event handler.
1646          *
1647          * @param handler the new content handler
1648          *******************************************************************************/
1649         public void setSaxHandler(SaxHandler handler) {
1650                 saxHandler = handler;
1651         }
1652 
1653         /*******************************************************************************
1654          * Get the content event handler.
1655          *
1656          * @return The current content handler, or null if none was set.
1657          *******************************************************************************/
1658         public SaxHandler getSaxHandler() {
1659                 return saxHandler;
1660         }
1661 
1662         /*******************************************************************************
1663          * Set the error event handler.
1664          *
1665          * @param handler the new error handler
1666          *******************************************************************************/
1667         public void setErrorHandler(ErrorHandler handler) {
1668                 errorHandler = handler;
1669         }
1670 
1671         /*******************************************************************************
1672          * Get the current error event handler.
1673          *
1674          * @return The current error handler, or null if none was set.
1675          *******************************************************************************/
1676         public ErrorHandler getErrorHandler() {
1677                 return errorHandler;
1678         }
1679 
1680         /*******************************************************************************
1681          * Parse a document.
1682          *
1683          * @param input The input source for the document entity.
1684          * @exception org.xml.sax.SAXException Any SAX exception, possibly
1685          *            wrapping another exception.
1686          * @exception java.io.IOException An IO exception from the parser,
1687          *            possibly from a byte stream or character stream
1688          *            supplied by the application.
1689          *******************************************************************************/
1690         private void parse(InputStream input) {
1691                 setupParse();
1692                 parent.parse(input);
1693         }
1694 
1695         /*******************************************************************************
1696          * Parse the given content.
1697          *
1698          * @param input The input source for the document entity.
1699          * @exception org.xml.sax.SAXException Any SAX exception, possibly
1700          *            wrapping another exception.
1701          * @exception java.io.IOException An IO exception from the parser,
1702          *            possibly from a byte stream or character stream
1703          *            supplied by the application.
1704          *******************************************************************************/
1705         public void parse(const(Ch)[] content) {
1706                 //TODO FIXME - create a buffer of this content as the input stream, and then parse.
1707                 //setupParse();
1708                 //parent.parse(input);
1709         }
1710 
1711         public void parse() {}
1712         public void setContent(const(Ch)[] content) {}
1713 
1714 
1715         /*******************************************************************************
1716          * Parse a document.
1717          *
1718          * @param systemId The system identifier as a fully-qualified URI.
1719          * @exception org.xml.sax.SAXException Any SAX exception, possibly
1720          *            wrapping another exception.
1721          * @exception java.io.IOException An IO exception from the parser,
1722          *            possibly from a byte stream or character stream
1723          *            supplied by the application.
1724          *******************************************************************************/
1725         private void parseUrl(const(Ch)[] systemId) {
1726                 //TODO FIXME
1727                 //parse(new InputSource(systemId));
1728         }
1729 
1730         ////////////////////////////////////////////////////////////////////
1731         // Implementation of org.xml.sax.EntityResolver.
1732         ////////////////////////////////////////////////////////////////////
1733         /*******************************************************************************
1734          * Filter an external entity resolution.
1735          *
1736          * @param publicId The entity's public identifier, or null.
1737          * @param systemId The entity's system identifier.
1738          * @return A new InputSource or null for the default.
1739          * @exception org.xml.sax.SAXException The client may throw
1740          *            an exception during processing.
1741          * @exception java.io.IOException The client may throw an
1742          *            I/O-related exception while obtaining the
1743          *            new InputSource.
1744          *******************************************************************************/
1745         public InputStream resolveEntity(const(Ch)[] publicId, const(Ch)[] systemId) {
1746                 if (entityResolver !is null) {
1747                         return entityResolver.resolveEntity(publicId, systemId);
1748                 }
1749                 else {
1750                         return null;
1751                 }
1752 
1753         }
1754 
1755         ////////////////////////////////////////////////////////////////////
1756         // Implementation of org.xml.sax.ContentHandler.
1757         ////////////////////////////////////////////////////////////////////
1758         /*******************************************************************************
1759          * Filter a new document locator event.
1760          *
1761          * @param locator The document locator.
1762          *******************************************************************************/
1763         public void setDocumentLocator(Locator locator) {
1764                 this.locator = locator;
1765                 if (saxHandler !is null) {
1766                         saxHandler.setDocumentLocator(locator);
1767                 }
1768 
1769         }
1770 
1771         /*******************************************************************************
1772          * Filter a start document event.
1773          *
1774          * @exception org.xml.sax.SAXException The client may throw
1775          *            an exception during processing.
1776          *******************************************************************************/
1777         public void startDocument() {
1778                 if (saxHandler !is null) {
1779                         saxHandler.startDocument();
1780                 }
1781 
1782         }
1783 
1784         /*******************************************************************************
1785          * Filter an end document event.
1786          *
1787          * @exception org.xml.sax.SAXException The client may throw
1788          *            an exception during processing.
1789          *******************************************************************************/
1790         public void endDocument() {
1791                 if (saxHandler !is null) {
1792                         saxHandler.endDocument();
1793                 }
1794 
1795         }
1796 
1797         /*******************************************************************************
1798          * Filter a start Namespace prefix mapping event.
1799          *
1800          * @param prefix The Namespace prefix.
1801          * @param uri The Namespace URI.
1802          * @exception org.xml.sax.SAXException The client may throw
1803          *            an exception during processing.
1804          *******************************************************************************/
1805         public void startPrefixMapping(const(Ch)[] prefix, const(Ch)[] uri) {
1806                 if (saxHandler !is null) {
1807                         saxHandler.startPrefixMapping(prefix, uri);
1808                 }
1809 
1810         }
1811 
1812         /*******************************************************************************
1813          * Filter an end Namespace prefix mapping event.
1814          *
1815          * @param prefix The Namespace prefix.
1816          * @exception org.xml.sax.SAXException The client may throw
1817          *            an exception during processing.
1818          *******************************************************************************/
1819         public void endPrefixMapping(const(Ch)[] prefix) {
1820                 if (saxHandler !is null) {
1821                         saxHandler.endPrefixMapping(prefix);
1822                 }
1823 
1824         }
1825 
1826         /*******************************************************************************
1827          * Filter a start element event.
1828          *
1829          * @param uri The element's Namespace URI, or the empty string.
1830          * @param localName The element's local name, or the empty string.
1831          * @param qName The element's qualified (prefixed) name, or the empty
1832          *        string.
1833          * @param atts The element's attributes.
1834          * @exception org.xml.sax.SAXException The client may throw
1835          *            an exception during processing.
1836          *******************************************************************************/
1837         public void startElement(const(Ch)[] uri, const(Ch)[] localName, const(Ch)[] qName, Attribute[] atts) {
1838                 if (saxHandler !is null) {
1839                         saxHandler.startElement(uri, localName, qName, atts);
1840                 }    
1841 
1842         }
1843 
1844         /*******************************************************************************
1845          * Filter an end element event.
1846          *
1847          * @param uri The element's Namespace URI, or the empty string.
1848          * @param localName The element's local name, or the empty string.
1849          * @param qName The element's qualified (prefixed) name, or the empty
1850          *        string.
1851          * @exception org.xml.sax.SAXException The client may throw
1852          *            an exception during processing.
1853          *******************************************************************************/
1854         public void endElement(const(Ch)[] uri, const(Ch)[] localName, const(Ch)[] qName) {
1855                 if (saxHandler !is null) {
1856                         saxHandler.endElement(uri, localName, qName);
1857                 }
1858 
1859         }
1860 
1861         /*******************************************************************************
1862          * Filter a character data event.
1863          *
1864          * @param ch An array of characters.
1865          * @exception org.xml.sax.SAXException The client may throw
1866          *            an exception during processing.
1867          *******************************************************************************/
1868         public void characters(Ch ch[]) {
1869                 if (saxHandler !is null) {
1870                         saxHandler.characters(ch);
1871                 }
1872 
1873         }
1874 
1875         /*******************************************************************************
1876          * Filter an ignorable whitespace event.
1877          *
1878          * @param ch An array of characters.
1879          * @param start The starting position in the array.
1880          * @param length The number of characters to use from the array.
1881          * @exception org.xml.sax.SAXException The client may throw
1882          *            an exception during processing.
1883          *******************************************************************************/
1884         public void ignorableWhitespace(Ch ch[]) {
1885                 if (saxHandler !is null) {
1886                         saxHandler.ignorableWhitespace(ch);
1887                 }
1888 
1889         }
1890 
1891         /*******************************************************************************
1892          * Filter a processing instruction event.
1893          *
1894          * @param target The processing instruction target.
1895          * @param data The text following the target.
1896          * @exception org.xml.sax.SAXException The client may throw
1897          *            an exception during processing.
1898          *******************************************************************************/
1899         public void processingInstruction(const(Ch)[] target, const(Ch)[] data) {
1900                 if (saxHandler !is null) {
1901                         saxHandler.processingInstruction(target, data);
1902                 }
1903 
1904         }
1905 
1906         /*******************************************************************************
1907          * Filter a skipped entity event.
1908          *
1909          * @param name The name of the skipped entity.
1910          * @exception org.xml.sax.SAXException The client may throw
1911          *            an exception during processing.
1912          *******************************************************************************/
1913         public void skippedEntity(const(Ch)[] name) {
1914                 if (saxHandler !is null) {
1915                         saxHandler.skippedEntity(name);
1916                 }
1917 
1918         }
1919 
1920         ////////////////////////////////////////////////////////////////////
1921         // Implementation of org.xml.sax.ErrorHandler.
1922         ////////////////////////////////////////////////////////////////////
1923         /*******************************************************************************
1924          * Filter a warning event.
1925          *
1926          * @param e The warning as an exception.
1927          * @exception org.xml.sax.SAXException The client may throw
1928          *            an exception during processing.
1929          *******************************************************************************/
1930         public void warning(SAXException e) {
1931                 if (errorHandler !is null) {
1932                         errorHandler.warning(e);
1933                 }
1934 
1935         }
1936 
1937         /*******************************************************************************
1938          * Filter an error event.
1939          *
1940          * @param e The error as an exception.
1941          * @exception org.xml.sax.SAXException The client may throw
1942          *            an exception during processing.
1943          *******************************************************************************/
1944         public void error(SAXException e) {
1945                 if (errorHandler !is null) {
1946                         errorHandler.error(e);
1947                 }
1948 
1949         }
1950 
1951         /*******************************************************************************
1952          * Filter a fatal error event.
1953          *
1954          * @param e The error as an exception.
1955          * @exception org.xml.sax.SAXException The client may throw
1956          *            an exception during processing.
1957          *******************************************************************************/
1958         public void fatalError(SAXException e) {
1959                 if (errorHandler !is null) {
1960                         errorHandler.fatalError(e);
1961                 }
1962 
1963         }
1964 
1965         ////////////////////////////////////////////////////////////////////
1966         // Internal methods.
1967         ////////////////////////////////////////////////////////////////////
1968         /*******************************************************************************
1969          * Set up before a parse.
1970          *
1971          * <p>Before every parse, check whether the parent is
1972          * non-null, and re-register the filter for all of the 
1973          * events.</p>
1974          *******************************************************************************/
1975         private void setupParse() {
1976                 if (parent is null) {
1977                         throw new Exception("No parent for filter");
1978                 }
1979                 parent.setEntityResolver(this);
1980                 parent.setSaxHandler(this);
1981                 parent.setErrorHandler(this);
1982         }
1983 
1984         ////////////////////////////////////////////////////////////////////
1985         // Internal state.
1986         ////////////////////////////////////////////////////////////////////
1987         private XMLReader parent = null;
1988 
1989         private Locator locator = null;
1990 
1991         private EntityResolver entityResolver = null;
1992 
1993         private SaxHandler saxHandler = null;
1994 
1995         private ErrorHandler errorHandler = null;
1996 
1997 }
1998 
1999 
2000 
2001 /*******************************************************************************
2002  * Interface for reading an XML document using callbacks.
2003  *
2004  * <p>XMLReader is the interface that an XML parser's SAX2 driver must
2005  * implement.  This interface allows an application to set and
2006  * query features and properties in the parser, to register
2007  * event handlers for document processing, and to initiate
2008  * a document parse.</p>
2009  *
2010  * <p>All SAX interfaces are assumed to be synchronous: the
2011  * {@link #parse parse} methods must not return until parsing
2012  * is complete, and readers must wait for an event-handler callback
2013  * to return before reporting the next event.</p>
2014  *
2015  * <p>This interface replaces the (now deprecated) SAX 1.0 {@link
2016  * org.xml.sax.Parser Parser} interface.  The XMLReader interface
2017  * contains two important enhancements over the old Parser
2018  * interface (as well as some minor ones):</p>
2019  *
2020  * <ol>
2021  * <li>it adds a standard way to query and set features and 
2022  *  properties; and</li>
2023  * <li>it adds Namespace support, which is required for many
2024  *  higher-level XML standards.</li>
2025  * </ol>
2026  *
2027  * <p>There are adapters available to convert a SAX1 Parser to
2028  * a SAX2 XMLReader and vice-versa.</p>
2029  *
2030  * @since SAX 2.0
2031  * @author David Megginson
2032  * @version 2.0.1+ (sax2r3pre1)
2033  * @see org.xml.sax.XMLFilter
2034  * @see org.xml.sax.helpers.ParserAdapter
2035  * @see org.xml.sax.helpers.XMLReaderAdapter 
2036  *******************************************************************************/
2037 public interface XMLReader(Ch = char) {
2038 
2039         ////////////////////////////////////////////////////////////////////
2040         // Configuration.
2041         ////////////////////////////////////////////////////////////////////
2042         /*******************************************************************************
2043          * Look up the value of a feature flag.
2044          *
2045          * <p>The feature name is any fully-qualified URI.  It is
2046          * possible for an XMLReader to recognize a feature name but
2047          * temporarily be unable to return its value.
2048          * Some feature values may be available only in specific
2049          * contexts, such as before, during, or after a parse.
2050          * Also, some feature values may not be programmatically accessible.
2051          * (In the case of an adapter for SAX1 {@link Parser}, there is no
2052          * implementation-independent way to expose whether the underlying
2053          * parser is performing validation, expanding external entities,
2054          * and so forth.) </p>
2055          *
2056          * <p>All XMLReaders are required to recognize the
2057          * http://xml.org/sax/features/namespaces and the
2058          * http://xml.org/sax/features/namespace-prefixes feature names.</p>
2059          *
2060          * <p>Typical usage is something like this:</p>
2061          *
2062          * <pre>
2063          * XMLReader r = new MySAXDriver();
2064          *
2065          *                         // try to activate validation
2066          * try {
2067          *   r.setFeature("http://xml.org/sax/features/validation", true);
2068          * } catch (SAXException e) {
2069          *   System.err.println("Cannot activate validation."); 
2070          * }
2071          *
2072          *                         // register event handlers
2073          * r.setContentHandler(new MyContentHandler());
2074          * r.setErrorHandler(new MyErrorHandler());
2075          *
2076          *                         // parse the first document
2077          * try {
2078          *   r.parse("http://www.foo.com/mydoc.xml");
2079          * } catch (IOException e) {
2080          *   System.err.println("I/O exception reading XML document");
2081          * } catch (SAXException e) {
2082          *   System.err.println("XML exception reading document.");
2083          * }
2084          * </pre>
2085          *
2086          * <p>Implementors are free (and encouraged) to invent their own features,
2087          * using names built on their own URIs.</p>
2088          *
2089          * @param name The feature name, which is a fully-qualified URI.
2090          * @return The current value of the feature (true or false).
2091          * @exception org.xml.sax.SAXNotRecognizedException If the feature
2092          *            value can't be assigned or retrieved.
2093          * @exception org.xml.sax.SAXNotSupportedException When the
2094          *            XMLReader recognizes the feature name but 
2095          *            cannot determine its value at this time.
2096          * @see #setFeature
2097          *******************************************************************************/
2098         public bool getFeature(const(Ch)[] name);
2099 
2100         /*******************************************************************************
2101          * Set the value of a feature flag.
2102          *
2103          * <p>The feature name is any fully-qualified URI.  It is
2104          * possible for an XMLReader to expose a feature value but
2105          * to be unable to change the current value.
2106          * Some feature values may be immutable or mutable only 
2107          * in specific contexts, such as before, during, or after 
2108          * a parse.</p>
2109          *
2110          * <p>All XMLReaders are required to support setting
2111          * http://xml.org/sax/features/namespaces to true and
2112          * http://xml.org/sax/features/namespace-prefixes to false.</p>
2113          *
2114          * @param name The feature name, which is a fully-qualified URI.
2115          * @param value The requested value of the feature (true or false).
2116          * @exception org.xml.sax.SAXNotRecognizedException If the feature
2117          *            value can't be assigned or retrieved.
2118          * @exception org.xml.sax.SAXNotSupportedException When the
2119          *            XMLReader recognizes the feature name but 
2120          *            cannot set the requested value.
2121          * @see #getFeature
2122          *******************************************************************************/
2123         public void setFeature(const(Ch)[] name, bool value);
2124 
2125         /*******************************************************************************
2126          * Look up the value of a property.
2127          *
2128          * <p>The property name is any fully-qualified URI.  It is
2129          * possible for an XMLReader to recognize a property name but
2130          * temporarily be unable to return its value.
2131          * Some property values may be available only in specific
2132          * contexts, such as before, during, or after a parse.</p>
2133          *
2134          * <p>XMLReaders are not required to recognize any specific
2135          * property names, though an initial core set is documented for
2136          * SAX2.</p>
2137          *
2138          * <p>Implementors are free (and encouraged) to invent their own properties,
2139          * using names built on their own URIs.</p>
2140          *
2141          * @param name The property name, which is a fully-qualified URI.
2142          * @return The current value of the property.
2143          * @exception org.xml.sax.SAXNotRecognizedException If the property
2144          *            value can't be assigned or retrieved.
2145          * @exception org.xml.sax.SAXNotSupportedException When the
2146          *            XMLReader recognizes the property name but 
2147          *            cannot determine its value at this time.
2148          * @see #setProperty
2149          *******************************************************************************/
2150         public Object getProperty(const(Ch)[] name);
2151 
2152         /*******************************************************************************
2153          * Set the value of a property.
2154          *
2155          * <p>The property name is any fully-qualified URI.  It is
2156          * possible for an XMLReader to recognize a property name but
2157          * to be unable to change the current value.
2158          * Some property values may be immutable or mutable only 
2159          * in specific contexts, such as before, during, or after 
2160          * a parse.</p>
2161          *
2162          * <p>XMLReaders are not required to recognize setting
2163          * any specific property names, though a core set is defined by 
2164          * SAX2.</p>
2165          *
2166          * <p>This method is also the standard mechanism for setting
2167          * extended handlers.</p>
2168          *
2169          * @param name The property name, which is a fully-qualified URI.
2170          * @param value The requested value for the property.
2171          * @exception org.xml.sax.SAXNotRecognizedException If the property
2172          *            value can't be assigned or retrieved.
2173          * @exception org.xml.sax.SAXNotSupportedException When the
2174          *            XMLReader recognizes the property name but 
2175          *            cannot set the requested value.
2176          *******************************************************************************/
2177         public void setProperty(const(Ch)[] name, Object value);
2178 
2179         ////////////////////////////////////////////////////////////////////
2180         // Event handlers.
2181         ////////////////////////////////////////////////////////////////////
2182         /*******************************************************************************
2183          * Allow an application to register an entity resolver.
2184          *
2185          * <p>If the application does not register an entity resolver,
2186          * the XMLReader will perform its own default resolution.</p>
2187          *
2188          * <p>Applications may register a new or different resolver in the
2189          * middle of a parse, and the SAX parser must begin using the new
2190          * resolver immediately.</p>
2191          *
2192          * @param resolver The entity resolver.
2193          * @see #getEntityResolver
2194          *******************************************************************************/
2195         public void setEntityResolver(EntityResolver!(Ch) resolver);
2196 
2197         /*******************************************************************************
2198          * Return the current entity resolver.
2199          *
2200          * @return The current entity resolver, or null if none
2201          *         has been registered.
2202          * @see #setEntityResolver
2203          *******************************************************************************/
2204         public EntityResolver!(Ch) getEntityResolver();
2205 
2206         /*******************************************************************************
2207          * Allow an application to register a content event handler.
2208          *
2209          * <p>If the application does not register a content handler, all
2210          * content events reported by the SAX parser will be silently
2211          * ignored.</p>
2212          *
2213          * <p>Applications may register a new or different handler in the
2214          * middle of a parse, and the SAX parser must begin using the new
2215          * handler immediately.</p>
2216          *
2217          * @param handler The content handler.
2218          * @see #getContentHandler
2219          *******************************************************************************/
2220         public void setSaxHandler(SaxHandler!(Ch) handler);
2221 
2222         /*******************************************************************************
2223          * Return the current content handler.
2224          *
2225          * @return The current content handler, or null if none
2226          *         has been registered.
2227          * @see #setContentHandler
2228          *******************************************************************************/
2229         public SaxHandler!(Ch) getSaxHandler();
2230 
2231         /*******************************************************************************
2232          * Allow an application to register an error event handler.
2233          *
2234          * <p>If the application does not register an error handler, all
2235          * error events reported by the SAX parser will be silently
2236          * ignored; however, normal processing may not continue.  It is
2237          * highly recommended that all SAX applications implement an
2238          * error handler to avoid unexpected bugs.</p>
2239          *
2240          * <p>Applications may register a new or different handler in the
2241          * middle of a parse, and the SAX parser must begin using the new
2242          * handler immediately.</p>
2243          *
2244          * @param handler The error handler.
2245          * @see #getErrorHandler
2246          *******************************************************************************/
2247         public void setErrorHandler(ErrorHandler!(Ch) handler);
2248 
2249         /*******************************************************************************
2250          * Return the current error handler.
2251          *
2252          * @return The current error handler, or null if none
2253          *         has been registered.
2254          * @see #setErrorHandler
2255          *******************************************************************************/
2256         public ErrorHandler!(Ch) getErrorHandler();
2257 
2258         ////////////////////////////////////////////////////////////////////
2259         // Parsing.
2260         ////////////////////////////////////////////////////////////////////
2261         /*******************************************************************************
2262          * Parse an XML document.
2263          *
2264          * <p>The application can use this method to instruct the XML
2265          * reader to begin parsing an XML document from any valid input
2266          * source (a character stream, a byte stream, or a URI).</p>
2267          *
2268          * <p>Applications may not invoke this method while a parse is in
2269          * progress (they should create a new XMLReader instead for each
2270          * nested XML document).  Once a parse is complete, an
2271          * application may reuse the same XMLReader object, possibly with a
2272          * different input source.
2273          * Configuration of the XMLReader object (such as handler bindings and
2274          * values established for feature flags and properties) is unchanged
2275          * by completion of a parse, unless the definition of that aspect of
2276          * the configuration explicitly specifies other behavior.
2277          * (For example, feature flags or properties exposing
2278          * characteristics of the document being parsed.)
2279          * </p>
2280          *
2281          * <p>During the parse, the XMLReader will provide information
2282          * about the XML document through the registered event
2283          * handlers.</p>
2284          *
2285          * <p>This method is synchronous: it will not return until parsing
2286          * has ended.  If a client application wants to terminate 
2287          * parsing early, it should throw an exception.</p>
2288          *
2289          * @param input The input source for the top-level of the
2290          *        XML document.
2291          * @exception org.xml.sax.SAXException Any SAX exception, possibly
2292          *            wrapping another exception.
2293          * @exception java.io.IOException An IO exception from the parser,
2294          *            possibly from a byte stream or character stream
2295          *            supplied by the application.
2296          * @see org.xml.sax.InputSource
2297          * @see #parse(java.lang.String)
2298          * @see #setEntityResolver
2299          * @see #setContentHandler
2300          * @see #setErrorHandler 
2301          *******************************************************************************/
2302         private void parse(InputStream input);
2303 
2304         /*******************************************************************************
2305          * Parse an XML document from a system identifier (URI).
2306          *
2307          * <p>This method is a shortcut for the common case of reading a
2308          * document from a system identifier.  It is the exact
2309          * equivalent of the following:</p>
2310          *
2311          * <pre>
2312          * parse(new InputSource(systemId));
2313          * </pre>
2314          *
2315          * <p>If the system identifier is a URL, it must be fully resolved
2316          * by the application before it is passed to the parser.</p>
2317          *
2318          * @param systemId The system identifier (URI).
2319          * @exception org.xml.sax.SAXException Any SAX exception, possibly
2320          *            wrapping another exception.
2321          * @exception java.io.IOException An IO exception from the parser,
2322          *            possibly from a byte stream or character stream
2323          *            supplied by the application.
2324          * @see #parse(org.xml.sax.InputSource)
2325          *******************************************************************************/
2326         private void parseUrl(const(Ch)[] systemId);
2327 
2328         /*******************************************************************************
2329          * Parse an XML document from a character array.
2330          *
2331          * @param content The actual document content.
2332          * @exception org.xml.sax.SAXException Any SAX exception, possibly
2333          *            wrapping another exception.
2334          * @exception java.io.IOException An IO exception from the parser,
2335          *            possibly from a byte stream or character stream
2336          *            supplied by the application.
2337          * @see #parse(org.xml.sax.InputSource)
2338          *******************************************************************************/
2339         public void parse(const(Ch)[] content);
2340 
2341         /*******************************************************************************
2342          *******************************************************************************/
2343         public void parse();
2344 
2345         /*******************************************************************************
2346          *******************************************************************************/
2347         public void setContent(const(Ch)[] content);
2348 
2349 }