AElfred, Version 1.1 Microstar's Java-Based XML Parser From: http://www.microstar.com/XML/README.txt, 980309 Copyright (c) 1997, 1998 by Microstar Software Ltd. Author: David Megginson dmeggins@microstar.com Home Page: http://www.microstar.com/XML/ AElfred is free for both commercial and non-commercial use and redistribution, provided that Microstar's copyright and disclaimer are retained intact. DISCLAIMER ---------- This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of merchantability or fitness for a particular purpose. Please use it AT YOUR OWN RISK. ** NEWS ** ---------- MAJOR REDESIGN, 1998-03-08: - AElfred can read a document from an InputStream as well as a URI. - AElfred reports the column position as well as the line number for errors - AElfred now respects the content encoding specified by HTTP, if any - AElfred now provides a usable byte offset for encoding errors - The XmlProcessor interface has been renamed to XmlHandler - A optional SAX driver (com.microstar.xml.SAXDriver) is now bundled with the AElfred distribution - An optional handler base class (com.microstar.xml.HandlerBase) is now bundled with the AElfred distribution - An optional exception class (com.microstar.xml.XmlException) is now bundled with the AElfred distribution, and used by HandlerBase - XmlParser now has only an empty constructor - use XmlParser.setHandler to set the XmlHandler - use XmlParser.parse(String, String) to parse from a URI - use XmlParser.parse(String, String, InputStream) to parse from an InputStream - AElfred no longer passes an XmlParser argument to any XmlHandler methods - XmlHandler.error now takes a column argument - XmlHandler.charData and XmlHandler.ignorableWhitespace now take a start argument - XmlHandler.endDocument no longer takes an errorCount argument DESIGN PRINCIPLES ----------------- In most Java applets and applications, XML should not be the central feature; instead, XML is the means to another end, such as loading configuration information, reading meta-data, or parsing transactions. When an XML parser is only a single component of a much larger program, it cannot be large, slow, or resource-intensive. With Java applets, in particular, few programmers would be willing to require users to download an additional 50K to 100K in class files just for the sake of adding XML capability. AElfred is a new Java-based XML parser from Microstar Software Ltd. (http://www.microstar.com/), an established provider of XML and SGML solutions. AElfred is distributed for free (with full source) for both commercial and non-commercial use, and is designed for easy and efficient use over the Internet, based on the following principles: 1. AElfred must be as small as possible, so that it doesn't add too much to your applet's download time. STATUS: AElfred is currently about 26K in total. The compressed JAR file, including the optional classes, is only 15K. 2. AElfred must use as few class files as possible, to minimize the number of HTTP connections necessary. STATUS: AElfred consists of only two core class files, the main parser class (XmlParser.class) and a small interface for your own program to implement (XmlHandler.class). All other classes in the distribution are either optional or for demonstration only. 3. AElfred must be compatible with most or all Java implementations and platforms. STATUS: AElfred uses only JDK 1.0.2 features, and we have tested it successfully with the following Java implementations: JDK 1.1.1 (Linux), jview (Windows NT), Netscape 4 (Linux and Windows NT), Internet Explorer 3 (Windows NT), and Internet Explorer 4 (Windows NT). 4. AElfred must use as little memory as possible, so that it does not take away resources from the rest of your program. STATUS: On a P75 Linux system, using JDK 1.1.1, running AElfred (with a 4MB XML document) takes only 2MB more memory than running a simple "Hello world" Java application. Because AElfred does not build an in-memory parse tree, you can run it on very large input files using little or no extra memory. 5. AElfred must run as fast as possible, so that it does not slow down the rest of your program. STATUS: On a P75 Linux system, using JDK 1.1.1 (without a JIT compiler), AElfred parses test files at about 70K/second. On a P166 NT workstation, using jview, AElfred parses test files at about about 1MB/second. 6. AElfred must produce correct output for well-formed and valid documents, but need not reject every document that is not valid or not well-formed. STATUS: AElfred is DTD-aware, and handles all current XML features, including CDATA and INCLUDE/IGNORE marked sections, internal and external entities, proper whitespace treatment in element content, and default attribute values. It will sometimes accept input that is technically incorrect, however, without reporting an error (see below), since full error reporting would make the parser larger. 7. AElfred must provide full internationalisation from the first release. STATUS: AElfred supports Unicode to the fullest extent possible in Java. It correctly handles XML documents encoded using UTF-8, UTF-16, ISO-10646-UCS-2, ISO-10646-UCS-4 (as far as surrogates allow), and ISO-8859-1 (ISO Latin 1/Windows). With these character sets, AElfred can handle all of the world's major (and most of its minor) languages. As you can see from this list, AElfred is designed for production use, not for validation: it will behave correctly with correct files, but it will not necessarily let you know when there are errors. If you want to verify on your system that your XML document is valid or well-formed before you publish it to the Internet, then you should use a validating XML parser. SAX --- AElfred now has a SAX driver built-in to the main distribution, so there is no need to use an external driver. The class name of the driver is com.microstar.xml.SAXDriver STARTUP ------- To test the parser, you can try one of the demonstration applications EventDemo, TimerDemo, DtdDemo, or StreamDemo (see descriptions below). To start an application, make certain that AElfred's classes are somewhere on your CLASSPATH, then use a command line like the following: java EventDemo Where can be relative (i.e. a file in the current directory) or absolute (i.e. an XML document anywhere on the Internet). Note that StreamDemo takes a file name rather than a URI. XML parsers like AElfred read one or more source files (called "entities"), and merge them into a single stream of logical events, such as character data, processing instructions, or the start or end of elements. The EventDemo demonstration application gives you an idea of what information appears in the stream. PROGRAMMER'S USAGE ------------------ To use AElfred in your own Java applets or applications, you need to supply a class that implements the com.microstar.xml.XmlHandler interface (say, "MyHandler"), create a new com.microstar.xml.XmlParser object (supplying the URI of the XML document), then explicitly start a parse: import com.microstar.xml.XmlParser; [...] String uri = "http://www.host.com/sample.xml"; MyHandler handler = new MyHandler(); XmlParser parser = new XmlParser(); parser.setHandler(handler); parser.parse(uri, null); During the parse, AElfred will call methods in your handler to report events; for example, whenever a new element begins, it will call your method void startElement(String name) There are thirteen callback methods altogether in the XmlHandler interface; for details, see HTML/com.microstar.xml.XmlHandler.html: public void startDocument (); public void endDocument (); public String resolveEntity (String ename, String publicId, String systemId); public String startExternalEntity (String systemId); public String endExternalEntity (String systemId); public void doctypeDecl (String dname, String publicId, String systemId); public void attribute (String name, String value, boolean isSpecified); public void startElement (String elname); public void endElement (String elname); public void charData (char ch[], int start, int length); public void ignorableWhitespace (char ch[], int start, int length); public void processingInstruction (String target, String data); public void error (String message, String url, int line, int column); If you want to avoid implementing all of these, you can derive your handler from com.microstar.xml.HandlerBase (see below), then fill in only the ones you need. REQUIRED CLASSES ---------------- If you want to use the XML parser with a Java applet, these are the only two classes that you must install (in addition to your own class that implements the XmlHandler interface): com/microstar/xml/XmlParser.class The actual XML parser. com/microstar/xml/XmlHandler.class The callback interface for the XML parser. OPTIONAL CLASSES ---------------- There are three optional classes that you may choose to install on a web site (all are very small): com/microstar/xml/XmlException.class A convenience class for reporting XML parsing errors. com/microstar/xml/HandlerBase.class (Requires XmlException.class.) A base class that provides a default implementation for all the handlers. com/microstar/xml/SAXDriver.class A SAX driver for AElfred. Neither of the required classes refers to these, and you may leave them out of a web installation if you do not need them. DEMONSTRATION CLASSES --------------------- The distribution also contains some classes for the demonstration applications. Normally, you will not include these in a web installation: XmlApp.class A simple base class for the demonstrations. EventDemo.class (Requires XmlApp.class.) A demonstration application showing the XML parse events. TimerDemo.class (Requires XmlApp.class.) A demonstration application that simply parses a document without producing any running output (except for errors and warnings); useful for timing the parser on different documents. DtdDemo.class (Requires XmlApp.class.) A demonstration application that parses a document and prints out a normalised version of the document's DTD (if any). StreamDemo.class (Requires XmlApp.class.) A demonstration application that parses a document from an input stream rather than a URL. PARSER QUERY METHODS -------------------- In addition to receiving callbacks, your XmlHandler object can send queries about the DTD back to the XmlParser object. The results of these queries are not guaranteed complete until after your handler has received a doctypeDecl() event (for details of these query methods, see HTML/com.microstar.xml.XmlParser.html): package com.microstar.xml.XmlParser; public Enumeration declaredElements () public int getElementContentType (String elname) public String getElementContentModel (String elname) public Enumeration declaredAttributes (String elname) public int getAttributeType (String elname, String aname) public String getAttributeEnumeration (String elname, String aname) public String getAttributeDefaultValue (String elname, String aname) public String getAttributeExpandedValue (String elname, String aname) public String getAttributeDefaultValueType (String elname, String aname) public Enumeration declaredEntities () public int getEntityType (String ename) public String getEntityPublicId (String ename) public String getEntitySystemId (String ename) public String getEntityValue (String ename) public String getEntityNotationName (String ename) public Enumeration declaredNotations () public String getNotationPublicId (String nname) public String getNotationSystemId (String nname) CHARACTER ENCODINGS ------------------- ** WARNING: AS REQUIRED BY THE XML SPECIFICATION, AELFRED ASSUMES THAT 8-BIT CHARACTERS USE UTF-8 ENCODING UNLESS YOU PROVIDE AN ENCODING DECLARATION. UTF-8 IS NOT THE SAME AS ISO-8859-1, SO 8-BIT ACCENTED CHARACTERS WILL CAUSE AN ERROR UNLESS YOU EXPLICITLY DECLARE "ISO-8859-1" AS YOUR ENCODING. The AElfred parser currently supports all of the following input encodings: UTF-8 The 8-bit Unicode transformation encoding. UTF-16 The 16-bit Unicode transformation encoding (two octet orders). ISO-10646-UCS-2 The standard 16-bit Unicode encoding (two octet orders). ISO-10646-UCS-4 The standard 32-bit Unicode encoding (four octet orders). ISO-8859-1 The 8-bit standard used in HTML and by Windows and Unix. If you need only 7-bit characters (i.e. ASCII), you can declare the encoding as either "UTF-8" or "ISO-8859-1": If you use ISO-8859-1, the parser will run slightly faster, since it doesn't need to do any character transformation on input. If you do not declare an encoding, then the parser will (for 7- or 8-bit text) default to UTF-8, which will work for ASCII but is slightly slower. Since Java has only 16-bit characters, the parser does not resolve surrogate pairs in UTF-16; as a result, UTF-16 and UCS-2 are currently identical. ERRORS AND WARNINGS ------------------- AElfred should always produce correct output for valid and well-formed XML documents. Since AElfred is not a fully conforming XML parser, however, it will sometimes accept documents that are not well-formed or are not valid, without signaling an error. For example, James Clark has a error-reporting test suite available at ftp://ftp.jclark.com/pub/test/xmltest.zip These tests cover only well-formedness, not validity. With the 1997 version of this package, out of 141 tests AElfred _failed_ to report errors for 31 of them: 002.xml Illegal character at the start of a NAME. 006.xml '--' in comment. 014.xml '<' in attribute value 023.xml Illegal character at the start of a NAME. 024.xml Illegal character at the start of a NAME. 025.xml ']]>' in PCDATA. 026.xml ']]>' in PCDATA. 029.xml ']]>' in PCDATA. 030.xml Illegal XML character (formfeed). 031.xml Illegal XML character (formfeed). 032.xml Illegal XML character (formfeed). 033.xml Illegal XML character (ESC). 034.xml Illegal XML character (formfeed). 038.xml Duplicate attribute assignment. 069.xml Missing space before 'NDATA'. 070.xml '--' in comment. 074.xml Element starting and ending in different entity. 086.xml '[' in public identifier. 087.xml '[' in public identifier. 088.xml ' ' in system literal. 089.xml NDATA parameter entity. 090.xml '<' in attribute value. 091.xml NDATA parameter entity. 096.xml Missing space before 'encoding'. 100.xml Wrong case for standalone value. 104.xml Element begins and ends in different entities. 116.xml Reference begins and ends in different entities. 117.xml Reference begins and ends in different entities. 119.xml Reference begins and ends in different entities. 140.xml Illegal character at start of NAME. 141.xml Illegal character in NAME. My experiments suggest that reporting all of these errors would add 10-15K to AElfred's size and slow down parsing by about 15 per cent. ABOUT THE NAME "AElfred" ----------------------- AElfred the Great (AElfred in ASCII) was king of Wessex, and at least nominally of all England, at the time of his death in 899AD. AElfred introduced a wide-spread literacy program in the hope that his people would learn to read English, at least, if Latin was too difficult for them. This AElfred hopes to bring another sort of literacy to Java, using XML, at least, if full SGML is too difficult. The initial "AE" ("Æ" in ISO-8859-1) is also a reminder that XML is not limited to ASCII. __end of README__