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