| Oracle9i XML Developer's Kits Guide - XDK Release 2 (9.2) Part Number A96621-01 |
|
This chapter contains the following sections:
Oracle provides a set of XML parsers for Java, C, C++, and PL/SQL. Each of these parsers is a standalone XML component that parses an XML document (or a standalone DTD or XML Schema) so that it can be processed by an application. This chapter discusses the parser for Java only. The other language versions are discussed in later chapters.
Library and command-line versions are provided supporting the following standards and features:
These APIs permit applications to access and manipulate an XML document as a tree structure in memory. This interface is used by such applications as editors.
Additional features include:
The parsers are available on all Oracle platforms.
Figure 4-1 shows an XML document inputting XML Parser for Java. The DOM or SAX parser interface parses the XML document. The parsed XML is then transferred to the application for further processing.
If a stylesheet is used, the DOM or SAX interface also parses and outputs the XSL commands. These are sent together with the parsed XML to the XSLT Processor where the selected stylesheet is applied and the transformed (new) XML document is then output.

DOM and SAX APIs are explained in "DOM and SAX APIs".
The classes and methods used to parse an XML document are illustrated in the following diagrams:
The classes and methods used by the XSLT Processor to apply stylesheets are illustrated in the following diagram:
The V2 versions of the XML Parsers include an integrated XSL Transformation (XSLT) Processor for transforming XML data using XSL stylesheets. Using the XSLT processor, you can transform XML documents from XML to XML, XML to HTML, or to virtually any other text-based format. See Figure 4-1.
| See Also:
Chapter 5, "XSLT Processor for Java" for complete details. |
The Java XML parser also supports XML Namespaces. Namespaces are a mechanism to resolve or avoid name collisions between element types (tags) or attributes in XML documents.
This mechanism provides "universal" namespace element types and attribute names whose scope extends beyond this manual.
Such tags are qualified by uniform resource identifiers (URIs), such as:
<oracle:EMP xmlns:oracle="http://www.oracle.com/xml"/>
For example, namespaces can be used to identify an Oracle <EMP> data element as distinct from another company's definition of an <EMP> data element.
This enables an application to more easily identify elements and attributes it is designed to process. The Java parser supports namespaces by being able to recognize and parse universal element types and attribute names, as well as unqualified "local" element types and attribute names.
The Java parser can parse XML in validating or non-validating modes.
Validation involves checking whether or not the attribute names and element tags are legal, whether nested elements belong where they are, and so on.
XML documents are made up of storage units called entities, which contain either parsed or unparsed data. Parsed data is made up of characters, some of which form character data, and some of which form markup.
Markup encodes a description of the document's storage layout and logical structure. XML provides a mechanism to impose constraints on the storage layout and logical structure.
A software module called an XML processor is used to read XML documents and provide access to their content and structure. It is assumed that an XML processor is doing its work on behalf of another module, called the application.
This parsing process is illustrated in Figure 4-2.

XML APIs generally fall into the following two categories:
See Figure 4-3. Consider the following simple XML document:
<?xml version="1.0"?> <EMPLIST> <EMP> <ENAME>MARY</ENAME> </EMP> <EMP> <ENAME>SCOTT</ENAME> </EMP> </EMPLIST>
A tree-based API (such as DOM) builds an in-memory tree representation of the XML document. It provides classes and methods for an application to navigate and process the tree.
In general, the DOM interface is most useful for structural manipulations of the XML tree, such as reordering elements, adding or deleting elements and attributes, renaming elements, and so on. For example, for the XML document preceding, the DOM creates an in-memory tree structure as shown inFigure 4-3.
An event-based API (such as SAX) uses calls to report parsing events to the application. The application deals with these events through customized event handlers. Events include the start and end of elements and characters.
Unlike tree-based APIs, event-based APIs usually do not build in-memory tree representations of the XML documents. Therefore, in general, SAX is useful for applications that do not need to manipulate the XML tree, such as search operations, among others.
The preceding XML document becomes a series of linear events as shown in Figure 4-3.

Here are some guidelines for using the DOM and SAX APIs:
Use the SAX API when your data is mostly streaming data.
This release supports binary compression of XML documents. The compression is based on tokenizing the XML tags. The assumption is that any XML document has a repeated number of tags and so tokenizing these tags will give considerable amount of compression. Therefore the compression achieved depends on the type of input document; the larger the tags and the lesser the text content, then the better the compression.
The goal of compression is to reduce the size of the XML document without loosing the structural and hierarchical information of the DOM tree. The compressed stream contains all the "useful" information to create the DOM tree back from the binary format. The compressed stream can also be generated from the SAX events. The binary stream generated from DOM and SAX are compatible. The compressed stream generated from SAX could be used to generate the DOM tree and vice versa.
Sample programs to illustrate the compression feature is included in demos.
Oracle XML Parser can also compress XML documents. Using the compression feature, an in-memory DOM tree or the SAX events generated from an XML document can be compressed to generate a binary compressed output.
The compressed stream generated from DOM and SAX are compatible, that is, the compressed stream generated from SAX could be used to generate the DOM tree and vice versa. The compression is based on tokenizing the XML tags. This is based on the assumption that XML files typically have repeated tags and tokenizing the tags compresses the data. The compression depends on the type of input XML document: the larger the number of tags, the less the text content, and the better the compression.
As with XML documents in general, you can store the compressed XML data output as a BLOB (Binary Large Object) in the database.
An XML document is compressed into a binary stream by means of the serialization of an in-memory DOM tree. When a large XML document is parsed and a DOM tree is created in memory corresponding to it, it may be difficult to satisfy memory requirements and this could affect performance. The XML document is compressed into a byte stream and stored in an in-memory DOM tree. This can be expanded at a later time into a DOM tree without performing validation on the XML data stored in the compressed stream.
The compressed stream can be treated as a serialized stream, but note that the information in the stream is more controlled and managed, compared to the compression implemented by Java's default serialization.
In this release, there are two kinds of XML compressed streams:
The compressed stream is generated using SAX events and that generated using DOM serialization are compatible. You can use the compressed stream generated by SAX events to create a DOM tree and vice versa. The compression algorithm used is based on tokenizing the XML tag's. The assumption is that any XML file has repeated number of tags and therefore tokenizing the tags will give considerable compression.
The directory demo/java/parser contains some sample XML applications to show how to use the Oracle XML parser.
The following are the sample Java files in the sub-directories:
The Tokenizer application implements XMLToken interface, which must be registered using the setTokenHandler() method. A request for the XML tokens is registered using the setToken() method. During tokenizing, the parser doesn't validate the document and does not include or read internal/external utilities.
To run these sample programs:
make to generate .class files.xmlparserv2.jar and the current directory to the CLASSPATH.java classname sample_xml_file
java XSLSample sample_xsl_file sample_xml_file
java Tokenizer sample_xml_file token_string
java DOMCompression sample.dat
The compressed output is generated in a file called "xml.ser"
java DeCompression xml.ser
java SAXCompression sample.dat
java SAXDeCompression xml.ser
java JAXPExamples
the .xml and .xsl are given inside JAXPExamples.java
A few .xml and files are provided as test cases in directory common.
The XSL stylesheet iden.xsl can be used to achieve an identity transformation of the XML files in a common directory.
<?xml version = "1.0"?> <!DOCTYPE course [ <!ELEMENT course (Name, Dept, Instructor, Student)> <!ELEMENT Name (#PCDATA)> <!ELEMENT Dept (#PCDATA)> <!ELEMENT Instructor (Name)> <!ELEMENT Student (Name*)> ]> <course> <Name>Calculus</Name> <Dept>Math</Dept> <Instructor> <Name>Jim Green</Name> </Instructor> <Student> <Name>Jack</Name> <Name>Mary</Name> <Name>Paul</Name> </Student> </course>
<?xml version="1.0"?> <!DOCTYPE employee [ <!ELEMENT employee (Name, Dept, Title)> <!ELEMENT Name (#PCDATA)> <!ELEMENT Dept (#PCDATA)> <!ELEMENT Title (#PCDATA)> ]> <employee> <Name>John Goodman</Name> <Dept>Manufacturing</Dept> <Title>Supervisor</Title> </employee>
<?xml version="1.0" standalone="no"?> <!DOCTYPE family SYSTEM "family.dtd"> <family lastname="Smith"> <member memberid="m1">Sarah</member> <member memberid="m2">Bob</member> <member memberid="m3" mom="m1" dad="m2">Joanne</member> <member memberid="m4" mom="m1" dad="m2">Jim</member> </family>
<!ELEMENT family (member*)> <!ATTLIST family lastname CDATA #REQUIRED> <!ELEMENT member (#PCDATA)> <!ATTLIST member memberid ID #REQUIRED> <!ATTLIST member dad IDREF #IMPLIED> <!ATTLIST member mom IDREF #IMPLIED>
<?xml version="1.0"?> <!-- Identity transformation --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="*|@*|comment()|processing-instruction()|text()"> <xsl:copy> <xsl:apply-templates select="*|@*|comment()|processing-instruction()|text()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
<!DOCTYPE doc [ <!ELEMENT doc (child*)> <!ATTLIST doc xmlns:nsprefix CDATA #IMPLIED> <!ATTLIST doc xmlns CDATA #IMPLIED> <!ATTLIST doc nsprefix:a1 CDATA #IMPLIED> <!ELEMENT child (#PCDATA)> ]> <doc nsprefix:a1 = "v1" xmlns="http://www.w3c.org" xmlns:nsprefix="http://www.oracle.com"> <child> This element inherits the default Namespace of doc. </child> </doc>
To write DOM based parser applications you can use the following classes:
Since DOMParser extends XMLParser, all methods of XMLParser are also available to DOMParser. Figure 4-4 shows the main steps you need when coding with the DOMParser() class:
DOMParser() class is called. Available properties to use with this class are:
DOMParser.reset() to clean up any internal data structures, once the Parser has finished building the DOM tree.DOMParser() class is called. The available properties to apply to this class are:
XMLParser.parseDTD() method along with the DTD input.XMLParser.getDocumentType() method then sends the resulting DTD object back to the new DOMParser() and the process continues until the DTD has been applied.The example, "XML Parser for Java Example 1: Using the Parser and DOM API", shows hoe to use DOMParser() class.

The examples represent the way we write code so it is required to present the examples with Java coding standards (like all imports expanded), with documentation headers before the methods, and so on.
// This file demonstates a simple use of the parser and DOM API. // The XML file given to the application is parsed. // The elements and attributes in the document are printed. // This demonstrates setting the parser options. // import java.io.*; import java.net.*; import org.w3c.dom.*; import org.w3c.dom.Node; import oracle.xml.parser.v2.*; public class DOMSample { static public void main(String[] argv) { try { if (argv.length != 1) { // Must pass in the name of the XML file. System.err.println("Usage: java DOMSample filename"); System.exit(1); } // Get an instance of the parser DOMParser parser = new DOMParser(); // Generate a URL from the filename. URL url = createURL(argv[0]); // Set various parser options: validation on, // warnings shown, error stream set to stderr. parser.setErrorStream(System.err); parser.setValidationMode(DTD_validation); parser.showWarnings(true); // Parse the document. parser.parse(url); // Obtain the document. XMLDocument doc = parser.getDocument(); // Print document elements System.out.print("The elements are: "); printElements(doc); // Print document element attributes System.out.println("The attributes of each element are: "); printElementAttributes(doc); parser.reset(); } catch (Exception e) { System.out.println(e.toString()); } } static void printElements(Document doc) { NodeList nl = doc.getElementsByTagName("*"); Node n; for (int i=0; i<nl.getLength(); i++) { n = nl.item(i); System.out.print(n.getNodeName() + " "); } System.out.println(); } static void printElementAttributes(Document doc) { NodeList nl = doc.getElementsByTagName("*"); Element e; Node n; NamedNodeMap nnm; String attrname; String attrval; int i, len; len = nl.getLength(); for (int j=0; j < len; j++) { e = (Element)nl.item(j); System.out.println(e.getTagName() + ":"); nnm = e.getAttributes(); if (nnm != null) { for (i=0; i<nnm.getLength(); i++) { n = nnm.item(i); attrname = n.getNodeName(); attrval = n.getNodeValue(); System.out.print(" " + attrname + " = " + attrval); } } System.out.println(); } } static URL createURL(String fileName) { URL url = null; try { url = new URL(fileName); } catch (MalformedURLException ex) { File f = new File(fileName); try { String path = f.getAbsolutePath(); String fs = System.getProperty("file.separator"); if (fs.length() == 1) { char sep = fs.charAt(0); if (sep != '/') path = path.replace(sep, '/'); if (path.charAt(0) != '/') path = '/' + path; } path = "file://" + path; url = new URL(path); } catch (MalformedURLException e) { System.out.println("Cannot create url for: " + fileName); System.exit(0); } } return url; } }
See also Figure 4-4. The following provides comments for Example 1:
DOMParser(). In Example 1, see the line:
DOMParser parser = new DOMParser();
This class has several properties you can use. Here the example uses:
parser.setErrorStream(System.err); parser.setValidationMode(DTD_validation); parser.showWarnings(true);
URL url = createURL(argv[0])
parser.parse(url);
XMLDocument doc = parser.getDocument();
Figure 4-3 illustrates the main processes involved when parsing an XML document using the DOM interface. The DOMNamespace() method is applied in the parser process at the "bubble" that states "Apply other DOM methods". The following example illustrates how to use DOMNamespace():
// This file demonstates a simple use of the parser and Namespace // extensions to the DOM APIs. // The XML file given to the application is parsed and the // elements and attributes in the document are printed. // import java.io.*; import java.net.*; import oracle.xml.parser.v2.DOMParser; import org.w3c.dom.*; import org.w3c.dom.Node; // Extensions to DOM Interfaces for Namespace support. import oracle.xml.parser.v2.XMLElement; import oracle.xml.parser.v2.XMLAttr; public class DOMNamespace { static public void main(String[] argv) { try { if (argv.length != 1) { // Must pass in the name of the XML file. System.err.println("Usage: DOMNamespace filename"); System.exit(1); } // Get an instance of the parser Class cls = Class.forName("oracle.xml.parser.v2.DOMParser"); DOMParser parser = (DOMParser)cls.newInstance(); // Generate a URL from the filename. URL url = createURL(argv[0]); // Parse the document. parser.parse(url); // Obtain the document. Document doc = parser.getDocument(); // Print document elements printElements(doc); // Print document element attributes System.out.println("The attributes of each element are: "); printElementAttributes(doc); } catch (Exception e) { System.out.println(e.toString()); } } static void printElements(Document doc) { NodeList nl = doc.getElementsByTagName("*"); XMLElement nsElement; String qName; String localName; String nsName; String expName; System.out.println("The elements are: "); for (int i=0; i < nl.getLength(); i++) { nsElement = (XMLElement)nl.item(i); // Use the methods getQualifiedName(), getLocalName(), getNamespace() // and getExpandedName() in NSName interface to get Namespace // information. qName = nsElement.getQualifiedName(); System.out.println(" ELEMENT Qualified Name:" + qName); localName = nsElement.getLocalName(); System.out.println(" ELEMENT Local Name :" + localName); nsName = nsElement.getNamespace(); System.out.println(" ELEMENT Namespace :" + nsName); expName = nsElement.getExpandedName(); System.out.println(" ELEMENT Expanded Name :" + expName); } System.out.println(); } static void printElementAttributes(Document doc) { NodeList nl = doc.getElementsByTagName("*"); Element e; XMLAttr nsAttr; String attrname; String attrval; String attrqname; NamedNodeMap nnm; int i, len; len = nl.getLength(); for (int j=0; j < len; j++) { e = (Element) nl.item(j); System.out.println(e.getTagName() + ":"); nnm = e.getAttributes(); if (nnm != null) { for (i=0; i < nnm.getLength(); i++) { nsAttr = (XMLAttr) nnm.item(i); // Use the methods getQualifiedName(), getLocalName(), // getNamespace() and getExpandedName() in NSName // interface to get Namespace information. attrname = nsAttr.getExpandedName(); attrqname = nsAttr.getQualifiedName(); attrval = nsAttr.getNodeValue(); System.out.println(" " + attrqname + "(" + attrname + ")" + " = " + attrval); } } System.out.println(); } } static URL createURL(String fileName) { URL url = null; try { url = new URL(fileName); } catch (MalformedURLException ex) { File f = new File(fileName); try { String path = f.getAbsolutePath(); String fs = System.getProperty("file.separator"); if (fs.length() == 1) { char sep = fs.charAt(0); if (sep != '/') path = path.replace(sep, '/'); if (path.charAt(0) != '/') path = '/' + path; } path = "file://" + path; url = new URL(path); } catch (MalformedURLException e) { System.out.println("Cannot create url for: " + fileName); System.exit(0); } } return url; } }
Applications can register a SAX handler to receive notification of various parser events. XMLReader is the interface that an XML parser's SAX2 driver must implement. This interface enables an application to set and query features and properties in the parser, to register event handlers for document processing, and to initiate a document parse.
All SAX interfaces are assumed synchronous: the parse methods must not return until parsing is complete, and readers must wait for an event-handler callback to return before reporting the next event.
This interface replaces the (now deprecated) SAX 1.0 Parser interface. The XMLReader interface contains two important enhancements over the old Parser interface:
Table 4-1 lists the class SAXParser() methods.
Figure 4-5 shows the main steps for coding with the SAXParser() class.
SAXParser() class. Table 4-1 lists the available methods.The example, "XML Parser for Java Example 3: Using the Parser and SAX API (SAXSample.java)", illustrates how you can use SAXParser() class and several handler interfaces.

// This file demonstates a simple use of the parser and SAX API. // The XML file given to the application is parsed and // prints out some information about the contents of this file. // import org.xml.sax.*; import java.io.*; import java.net.*; import oracle.xml.parser.v2.*; public class SAXSample extends HandlerBase { // Store the locator Locator locator; static public void main(String[] argv) { try { if (argv.length != 1) { // Must pass in the name of the XML file. System.err.println("Usage: SAXSample filename"); System.exit(1); } // (1) Create a new handler for the parser SAXSample sample = new SAXSample(); // (2) Get an instance of the parser Parser parser = new SAXParser(); // (3) Set Handlers in the parser parser.setDocumentHandler(sample); parser.setEntityResolver(sample); parser.setDTDHandler(sample); parser.setErrorHandler(sample); // (4) Convert file to URL and parse try { parser.parse(fileToURL(new File(argv[0])).toString()); } catch (SAXParseException e) { System.out.println(e.getMessage()); } catch (SAXException e) { System.out.println(e.getMessage()); } } catch (Exception e) { System.out.println(e.toString()); } } static URL fileToURL(File file) { String path = file.getAbsolutePath(); String fSep = System.getProperty("file.separator"); if (fSep != null && fSep.length() == 1) path = path.replace(fSep.charAt(0), '/'); if (path.length() > 0 && path.charAt(0) != '/') path = '/' + path; try { return new URL("file", null, path); } catch (java.net.MalformedURLException e) { throw new Error("unexpected MalformedURLException"); } } ////////////////////////////////////////////////////////////////////// // (5) Sample implementation of DocumentHandler interface. ////////////////////////////////////////////////////////////////////// public void setDocumentLocator (Locator locator) { System.out.println("SetDocumentLocator:"); this.locator = locator; } public void startDocument() { System.out.println("StartDocument"); } public void endDocument() throws SAXException { System.out.println("EndDocument"); } public void startElement(String name, AttributeList atts) throws SAXException { System.out.println("StartElement:"+name); for (int i=0;i<atts.getLength();i++) { String aname = atts.getName(i); String type = atts.getType(i); String value = atts.getValue(i); System.out.println(" "+aname+"("+type+")"+"="+value); } } public void endElement(String name) throws SAXException { System.out.println("EndElement:"+name); } public void characters(char[] cbuf, int start, int len) { System.out.print("Characters:"); System.out.println(new String(cbuf,start,len)); } public void ignorableWhitespace(char[] cbuf, int start, int len) { System.out.println("IgnorableWhiteSpace"); } public void processingInstruction(String target, String data) throws SAXException { System.out.println("ProcessingInstruction:"+target+" "+data); } ////////////////////////////////////////////////////////////////////// // (6) Sample implementation of the EntityResolver interface. ////////////////////////////////////////////////////////////////////// public InputSource resolveEntity (String publicId, String systemId) throws SAXException { System.out.println("ResolveEntity:"+publicId+" "+systemId); System.out.println("Locator:"+locator.getPublicId()+" "+ locator.getSystemId()+ " "+locator.getLineNumber()+" "+locator.getColumnNumber()); return null; } ////////////////////////////////////////////////////////////////////// // (7) Sample implementation of the DTDHandler interface. ////////////////////////////////////////////////////////////////////// public void notationDecl (String name, String publicId, String systemId) { System.out.println("NotationDecl:"+name+" "+publicId+" "+systemId); } public void unparsedEntityDecl (String name, String publicId, String systemId, String notationName) { System.out.println("UnparsedEntityDecl:"+name + " "+publicId+" "+ systemId+" "+notationName); } ////////////////////////////////////////////////////////////////////// // (8) Sample implementation of the ErrorHandler interface. ////////////////////////////////////////////////////////////////////// public void warning (SAXParseException e) throws SAXException { System.out.println("Warning:"+e.getMessage()); } public void error (SAXParseException e) throws SAXException { throw new SAXException(e.getMessage()); } public void fatalError (SAXParseException e) throws SAXException { System.out.println("Fatal error"); throw new SAXException(e.getMessage()); } }
// This file demonstrates a simple use of the Namespace extensions to // the SAX APIs. import org.xml.sax.*; import java.io.*; import java.net.URL; import java.net.MalformedURLException; // Extensions to the SAX Interfaces for Namespace support. import oracle.xml.parser.v2.XMLDocumentHandler; import oracle.xml.parser.v2.DefaultXMLDocumentHandler; import oracle.xml.parser.v2.NSName; import oracle.xml.parser.v2.SAXAttrList; import oracle.xml.parser.v2.SAXParser; public class SAXNamespace { static public void main(String[] args) { String fileName; //Get the file name if (args.length == 0) { System.err.println("No file Specified!!!"); System.err.println("USAGE: java SAXNamespace <filename>"); return; } else { fileName = args[0]; } try { // Create handlers for the parser // Use the XMLDocumentHandler interface for namespace support // instead of org.xml.sax.DocumentHandler XMLDocumentHandler xmlDocHandler = new XMLDocumentHandlerImpl(); // For all the other interface use the default provided by // Handler base HandlerBase defHandler = new HandlerBase(); // Get an instance of the parser SAXParser parser = new SAXParser(); // Set Handlers in the parser // Set the DocumentHandler to XMLDocumentHandler parser.setDocumentHandler(xmlDocHandler); // Set the other Handler to the defHandler parser.setErrorHandler(defHandler); parser.setEntityResolver(defHandler); parser.setDTDHandler(defHandler); try { parser.parse(fileToURL(new File(fileName)).toString()); } catch (SAXParseException e) { System.err.println(args[0] + ": " + e.getMessage()); } catch (SAXException e) { System.err.println(args[0] + ": " + e.getMessage()); } } catch (Exception e) { System.err.println(e.toString()); } } static public URL fileToURL(File file) { String path = file.getAbsolutePath(); String fSep = System.getProperty("file.separator"); if (fSep != null && fSep.length() == 1) path = path.replace(fSep.charAt(0), '/'); if (path.length() > 0 && path.charAt(0) != '/') path = '/' + path; try { return new URL("file", null, path); } catch (java.net.MalformedURLException e) { /* According to the spec this could only happen if the file /* protocol were not recognized. */ throw new Error("unexpected MalformedURLException"); } } private SAXNamespace() throws IOException { } } /*********************************************************************** Implementation of XMLDocumentHandler interface. Only the new startElement and endElement interfaces are implemented here. All other interfaces are implemented in the class HandlerBase. **********************************************************************/ class XMLDocumentHandlerImpl extends DefaultXMLDocumentHandler { public void XMLDocumentHandlerImpl() { } public void startElement(NSName name, SAXAttrList atts) throws SAXException { // Use the methods getQualifiedName(), getLocalName(), getNamespace() // and getExpandedName() in NSName interface to get Namespace // information. String qName; String localName; String nsName; String expName; qName = name.getQualifiedName(); System.out.println("ELEMENT Qualified Name:" + qName); localName = name.getLocalName(); System.out.println("ELEMENT Local Name :" + localName); nsName = name.getNamespace(); System.out.println("ELEMENT Namespace :" + nsName); expName = name.getExpandedName(); System.out.println("ELEMENT Expanded Name :" + expName); for (int i=0; i<atts.getLength(); i++) { // Use the methods getQualifiedName(), getLocalName(), getNamespace() // and getExpandedName() in SAXAttrList interface to get Namespace // information. qName = atts.getQualifiedName(i); localName = atts.getLocalName(i); nsName = atts.getNamespace(i); expName = atts.getExpandedName(i); System.out.println(" ATTRIBUTE Qualified Name :" + qName); System.out.println(" ATTRIBUTE Local Name :" + localName); System.out.println(" ATTRIBUTE Namespace :" + nsName); System.out.println(" ATTRIBUTE Expanded Name :" + expName); // You can get the type and value of the attributes either // by index or by the Qualified Name. String type = atts.getType(qName); String value = atts.getValue(qName); System.out.println(" ATTRIBUTE Type :" + type); System.out.println(" ATTRIBUTE Value :" + value); System.out.println(); } } public void endElement(NSName name) throws SAXException { // Use the methods getQualifiedName(), getLocalName(), getNamespace() // and getExpandedName() in NSName interface to get Namespace // information. String expName = name.getExpandedName(); System.out.println("ELEMENT Expanded Name :" + expName); } }
oraxml is a command-line interface to parse an XML document. It checks for well-formedness and validity.
To use oraxml ensure the following:
xmlparserv2.jar file that comes with Oracle XML V2 parser for Java. Because oraxml supports schema validation, include xschema.jar also in your CLASSPATHUse the following syntax to invoke oraxml:
oraxml options source
oraxml expects to be given an XML file to parse. Table 4-2 lists oraxml's command line options.
The Java API for XML Processing (JAXP) gives you the ability to use the SAX, DOM, and XSLT processors from your Java application. JAXP enables applications to parse and transform XML documents using an API that is independent of a particular XML processor implementation.
JAXP has a pluggability layer that enables you to plug in an implementation of a processor. The JAXP APIs have an API structure consisting of abstract classes providing a thin layer for parser pluggability. Oracle has implemented JAXP based on the Sun Microsystems reference implementation.
| See Also:
More examples can be found at the URL
and in the directory |
import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.sax.*; import javax.xml.transform.dom.*; import javax.xml.transform.stream.*; import java.io.*; import java.util.*; import java.net.URL; import java.net.MalformedURLException; import org.xml.sax.*; import org.xml.sax.ext.*; import org.xml.sax.helpers.*; import org.w3c.dom.*; public class JAXPExamples { public static void main(String argv[]) throws TransformerException, TransformerConfigurationException, IOException, SAXException, ParserConfigurationException, FileNotFoundException { try { URL xmlURL = createURL("jaxpone.xml"); String xmlID = xmlURL.toString(); URL xslURL = createURL("jaxpone.xsl"); String xslID = xslURL.toString(); // System.out.println("--- basic ---"); basic(xmlID, xslID); System.out.println(); System.out.println("--- identity ---"); identity(xmlID); // URL generalURL = createURL("general.xml"); String generalID = generalURL.toString(); URL ageURL = createURL("age.xsl"); String ageID = ageURL.toString(); System.out.println(); System.out.println("--- namespaceURI ---"); namespaceURI(generalID, ageID); // System.out.println(); System.out.println("--- templatesHandler ---"); templatesHandler(xmlID, xslID); System.out.println(); System.out.println("--- contentHandler2contentHandler ---"); contentHandler2contentHandler(xmlID, xslID); System.out.println(); System.out.println("--- contentHandler2DOM ---"); contentHandler2DOM(xmlID, xslID); System.out.println(); System.out.println("--- reader ---"); reader(xmlID, xslID); System.out.println(); System.out.println("--- xmlFilter ---"); xmlFilter(xmlID, xslID); // URL xslURLtwo = createURL("jaxptwo.xsl"); String xslIDtwo = xslURLtwo.toString(); URL xslURLthree = createURL("jaxpthree.xsl"); String xslIDthree = xslURLthree.toString(); System.out.println(); System.out.println("--- xmlFilterChain ---"); xmlFilterChain(xmlID, xslID, xslIDtwo, xslIDthree); } catch(Exception err) { err.printStackTrace(); } } // public static void basic(String xmlID, String xslID) throws TransformerException, TransformerConfigurationException { TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer transformer = tfactory.newTransformer(new StreamSource(xslID)); StreamSource source = new StreamSource(xmlID); transformer.transform(source, new StreamResult(System.out)); } // public static void identity(String xmlID) throws TransformerException, TransformerConfigurationException { TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer transformer = tfactory.newTransformer(); transformer.setOutputProperty(OutputKeys.METHOD, "html"); transformer.setOutputProperty(OutputKeys.INDENT, "no"); StreamSource source = new StreamSource(xmlID); transformer.transform(source, new StreamResult(System.out)); } // public static void namespaceURI(String xmlID, String xslID) throws TransformerException, TransformerConfigurationException { TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer transformer = tfactory.newTransformer(new StreamSource(xslID)); System.out.println("default: 99"); transformer.transform( new StreamSource(xmlID), new StreamResult(System.out)); transformer.setParameter("{http://www.oracle.com/ages}age", "20"); System.out.println(); System.out.println("should say: 20"); transformer.transform( new StreamSource(xmlID), new StreamResult(System.out)); transformer.setParameter("{http://www.oracle.com/ages}age", "40"); transformer.setOutputProperty(OutputKeys.METHOD, "html"); System.out.println(); System.out.println("should say: 40"); transformer.transform( new StreamSource(xmlID), new StreamResult(System.out)); } // public static void templatesHandler(String xmlID, String xslID) throws TransformerException, TransformerConfigurationException, IOException, SAXException, ParserConfigurationException, FileNotFoundException { TransformerFactory tfactory = TransformerFactory.newInstance(); if (tfactory.getFeature(SAXTransformerFactory.FEATURE)) { SAXTransformerFactory stfactory = (SAXTransformerFactory) tfactory; TemplatesHandler handler = stfactory.newTemplatesHandler(); handler.setSystemId(xslID); // JDK 1.1.8 Properties driver = System.getProperties(); driver.put("org.xml.sax.driver", "oracle.xml.parser.v2.SAXParser"); System.setProperties(driver); /** JDK 1.2.2 System.setProperty("org.xml.sax.driver", "oracle.xml.parser.v2.SAXParser"); */ XMLReader reader = XMLReaderFactory.createXMLReader(); reader.setContentHandler(handler); reader.parse(xslID); Templates templates = handler.getTemplates(); Transformer transformer = templates.newTransformer(); transformer.transform(new StreamSource(xmlID), new StreamResult(System.out)); } } // public static void reader(String xmlID, String xslID) throws TransformerException, TransformerConfigurationException, SAXException, IOException, ParserConfigurationException { TransformerFactory tfactory = TransformerFactory.newInstance(); SAXTransformerFactory stfactory = (SAXTransformerFactory)tfactory; StreamSource streamSource = new StreamSource(xslID); XMLReader reader = stfactory.newXMLFilter(streamSource); ContentHandler contentHandler = new oraContentHandler(); reader.setContentHandler(contentHandler); InputSource is = new InputSource(xmlID); reader.parse(is); } // public static void xmlFilter(String xmlID, String xslID) throws TransformerException, TransformerConfigurationException, SAXException, IOException, ParserConfigurationException { TransformerFactory tfactory = TransformerFactory.newInstance(); XMLReader reader = null; try { javax.xml.parsers.SAXParserFactory factory= javax.xml.parsers.SAXParserFactory.newInstance(); factory.setNamespaceAware(true); javax.xml.parsers.SAXParser jaxpParser= factory.newSAXParser(); reader = jaxpParser.getXMLReader(); } catch(javax.xml.parsers.ParserConfigurationException ex) { throw new org.xml.sax.SAXException(ex); } catch(javax.xml.parsers.FactoryConfigurationError ex1) { throw new org.xml.sax.SAXException(ex1.toString()); } catch(NoSuchMethodError ex2) { } if (reader == null) reader = XMLReaderFactory.createXMLReader(); XMLFilter filter = ((SAXTransformerFactory) tfactory).newXMLFilter(new StreamSource(xslID)); filter.setParent(reader); filter.setContentHandler(new oraContentHandler()); filter.parse(new InputSource(xmlID)); } // public static void xmlFilterChain( String xmlID, String xslID_1, String xslID_2, String xslID_3) throws TransformerException, TransformerConfigurationException, SAXException, IOException { TransformerFactory tfactory = TransformerFactory.newInstance(); if (tfactory.getFeature(SAXSource.FEATURE)) { SAXTransformerFactory stf = (SAXTransformerFactory)tfactory; XMLReader reader = null; try { javax.xml.parsers.SAXParserFactory factory = javax.xml.parsers.SAXParserFactory.newInstance(); factory.setNamespaceAware(true); javax.xml.parsers.SAXParser jaxpParser = factory.newSAXParser(); reader = jaxpParser.getXMLReader(); } catch(javax.xml.parsers.ParserConfigurationException ex) { throw new org.xml.sax.SAXException( ex ); } catch(javax.xml.parsers.FactoryConfigurationError ex1) { throw new org.xml.sax.SAXException( ex1.toString() ); } catch(NoSuchMethodError ex2) { } if (reader == null ) reader = XMLReaderFactory.createXMLReader(); XMLFilter filter1 = stf.newXMLFilter(new StreamSource(xslID_1)); XMLFilter filter2 = stf.newXMLFilter(new StreamSource(xslID_2)); XMLFilter filter3 = stf.newXMLFilter(new StreamSource(xslID_3)); if (filter1 != null && filter2 != null && filter3 != null) { filter1.setParent(reader); filter2.setParent(filter1); filter3.setParent(filter2); filter3.setContentHandler(new oraContentHandler()); filter3.parse(new InputSource(xmlID)); } } } // public static void contentHandler2contentHandler(String xmlID, String xslID) throws TransformerException, TransformerConfigurationException, SAXException, IOException { TransformerFactory tfactory = TransformerFactory.newInstance(); if (tfactory.getFeature(SAXSource.FEATURE)) { SAXTransformerFactory stfactory = ((SAXTransformerFactory) tfactory); TransformerHandler handler = stfactory.newTransformerHandler(new StreamSource(xslID)); Result result = new SAXResult(new oraContentHandler()); handler.setResult(result); XMLReader reader = null; try { javax.xml.parsers.SAXParserFactory factory= javax.xml.parsers.SAXParserFactory.newInstance(); factory.setNamespaceAware(true); javax.xml.parsers.SAXParser jaxpParser= factory.newSAXParser(); reader=jaxpParser.getXMLReader(); } catch( javax.xml.parsers.ParserConfigurationException ex ) { throw new org.xml.sax.SAXException( ex ); } catch( javax.xml.parsers.FactoryConfigurationError ex1 ) { throw new org.xml.sax.SAXException( ex1.toString() ); } catch( NoSuchMethodError ex2 ) { } if( reader == null ) reader = XMLReaderFactory.createXMLReader(); reader.setContentHandler(handler); reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); InputSource inputSource = new InputSource(xmlID); reader.parse(inputSource); } } // public static void contentHandler2DOM(String xmlID, String xslID) throws TransformerException, TransformerConfigurationException, SAXException, IOException, ParserConfigurationException { TransformerFactory tfactory = TransformerFactory.newInstance(); if (tfactory.getFeature(SAXSource.FEATURE) && tfactory.getFeature(DOMSource.FEATURE)) { SAXTransformerFactory sfactory = (SAXTransformerFactory) tfactory; DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); org.w3c.dom.Document outNode = docBuilder.newDocument(); TransformerHandler handler = sfactory.newTransformerHandler(new StreamSource(xslID)); handler.setResult(new DOMResult(outNode)); XMLReader reader = null; try { javax.xml.parsers.SAXParserFactory factory = javax.xml.parsers.SAXParserFactory.newInstance(); factory.setNamespaceAware(true); javax.xml.parsers.SAXParser jaxpParser= factory.newSAXParser(); reader = jaxpParser.getXMLReader(); } catch(javax.xml.parsers.ParserConfigurationException ex) { throw new org.xml.sax.SAXException(ex); } catch(javax.xml.parsers.FactoryConfigurationError ex1) { throw new org.xml.sax.SAXException(ex1.toString()); } catch(NoSuchMethodError ex2) { } if(reader == null ) reader = XMLReaderFactory.createXMLReader(); reader.setContentHandler(handler); reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); reader.parse(xmlID); printDOMNode(outNode); } } // private static void printDOMNode(Node node) throws TransformerException, TransformerConfigurationException, SAXException, IOException, ParserConfigurationException { TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer serializer = tfactory.newTransformer(); serializer.setOutputProperty(OutputKeys.METHOD, "xml"); serializer.setOutputProperty(OutputKeys.INDENT, "no"); serializer.transform(new DOMSource(node), new StreamResult(System.out)); } // private static URL createURL(String fileName) { URL url = null; try { url = new URL(fileName); } catch (MalformedURLException ex) { File f = new File(fileName); try { String path = f.getAbsolutePath(); // This is a bunch of weird code that is required to // make a valid URL on the Windows platform, due // to inconsistencies in what getAbsolutePath returns. String fs = System.getProperty("file.separator"); if (fs.length() == 1) { char sep = fs.charAt(0); if (sep != '/') path = path.replace(sep, '/'); if (path.charAt(0) != '/') path = '/' + path; } path = "file://" + path; url = new URL(path); } catch (MalformedURLException e) { System.out.println("Cannot create url for: " + fileName); System.exit(0); } } return url; } }
import org.xml.sax.ContentHandler; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.Locator; public class oraContentHandler implements ContentHandler { private static final String TRADE_MARK = "Oracle 9i "; public void setDocumentLocator(Locator locator) { System.out.println(TRADE_MARK + "- setDocumentLocator"); } public void startDocument() throws SAXException { System.out.println(TRADE_MARK + "- startDocument"); } public void endDocument() throws SAXException { System.out.println(TRADE_MARK + "- endDocument"); } public void startPrefixMapping(String prefix, String uri) throws SAXException { System.out.println(TRADE_MARK + "- startPrefixMapping: " + prefix + ", " + uri); } public void endPrefixMapping(String prefix) throws SAXException { System.out.println(TRADE_MARK + " - endPrefixMapping: " + prefix); } public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { System.out.print(TRADE_MARK + "- startElement: " + namespaceURI + ", " + namespaceURI + ", " + qName); int n = atts.getLength(); for(int i = 0; i < n; i++) System.out.print(", " + atts.getQName(i)); System.out.println(""); } public void endElement(String namespaceURI, String localName, String qName) throws SAXException { System.out.println(TRADE_MARK + "- endElement: " + namespaceURI + ", " + namespaceURI + ", " + qName); } public void characters(char ch[], int start, int length) throws SAXException { String s = new String(ch, start, (length > 30) ? 30 : length); if(length > 30) System.out.println(TRADE_MARK + "- characters: \"" + s + "\"..."); else System.out.println(TRADE_MARK + "- characters: \"" + s + "\""); } public void ignorableWhitespace(char ch[], int start, int length) throws SAXException { System.out.println(TRADE_MARK + "- ignorableWhitespace"); } public void processingInstruction(String target, String data) throws SAXException { System.out.println(TRADE_MARK + "- processingInstruction: " + target + ", " + target); } public void skippedEntity(String name) throws SAXException { System.out.println(TRADE_MARK + "- skippedEntity: " + name); } }
This section lists DTD questions and answers.
Answer: The DTD file defined in the <!DOCTYPE> declaration must be relative to the location of the input XML document. Otherwise, you'll need to use the setBaseURL(url) functions to set the base URL to resolve the relative address of the DTD if the input is coming from InputStream.
Answer: You need to include a reference to the applicable DTD in your XML document. Without it there is no way for the parser to know what to validate against. Including the reference is the XML standard way of specifying an external DTD. Otherwise you need to embed the DTD in your XML Document.
Do you have DTD caching? How do I set the DTD using version 2 of the parser for DTD Cache purpose?
Answer: Yes, DTD caching is optional and is not enabled automatically.
The method to set the DTD is setDoctype(). Here is an example:
// Test using InputSource parser = new DOMParser(); parser.setErrorStream(System.out); parser.showWarnings(true); FileReader r = new FileReader(args[0]); InputSource inSource = new InputSource(r); inSource.setSystemId(createURL(args[0]).toString()); parser.parseDTD(inSource, args[1]); dtd = (DTD)parser.getDoctype(); r = new FileReader(args[2]); inSource = new InputSource(r); inSource.setSystemId(createURL(args[2]).toString()); // ******************** parser.setDoctype(dtd); // ******************** parser.setValidationMode(DTD_validation); parser.parse(inSource);doc = (XMLDocument)parser.getDocument(); doc.print(new PrintWriter(System.out));
How does the XML Parser for Java version 2 recognize external DTDs when running from the server? The Java code has been loaded with loadjava and runs in the Oracle9i server process. My XML file has an external DTD reference.
resolveEntity()?Answer:
setBaseURL() method at this time.I would like to put all my DTDs in a JAR file, so that when the XML parser needs