XML Processing with Java
- Parsing XML Documents with DOM Level 2
- DOM Example: Representing an XML Document as a JTree
- Parsing XML Documents with SAX 2.0
- SAX Example 1: Printing the Outline of an XML Document
- SAX Example 2: Counting Book Orders
- Transforming XML with XSLT
- XSLT Example 1: XSLT Document Editor
- XSLT Example 2: Custom JSP Tag
- Summary
Topics in This Chapter
Representing an entire XML document using the Document Object Model (DOM) Level 2
Using DOM to display the outline of an XML document in a JTree
Responding to individual XML parsing events with the Simple API for XML Parsing (SAX) 2.0
Printing the outline of an XML document using SAX
Counting book orders using SAX
Transforming XML using XSLT
Invoking XSLT through custom JSP tags
Hiding vendor-specific details with the Java API for XML Processing (JAXP)
XML is a "meta" markup language used to describe the structure of data.
XML has numerous advantages including being easy to read, easy to parse, extensible, and widely adopted. In addition, you can define a grammar through a Docu_ment Type Definition (DTD) to enforce application-specific syntax. However, the greatest single advantage of XML is that the data can be easily processed by other applications; XML data is not in a proprietary format. In essence, XML has done for data what the Java language has done for programs:
Java = Portable Programs
XML = Portable Data
This chapter doesn't focus on how to write XML but rather how to process XML documents with Java. We show you how to use Java to process XML documents by using the Document Object Model (DOM), the Simple API for XML (SAX), and the Extensible Style sheet Language for Transformations (XSLT). If you are new to XML, here are some good starting points for additional information:
XML 1.0 Specification
Sun Page on XML and Java
WWW Consortium's Home Page on XML
Apache XML Project
XML Resource Collection
O'Reilly XML Resource Center
23.1 Parsing XML Documents with DOM Level 2
The Document Object Model (DOM) represents an entire XML document in a tree-like data structure that can be easily manipulated by a Java program. The advantages of DOM are that it is relatively simple to use and you can modify the data structure in addition to extracting data from it. However, the disadvantage is that DOM parses and stores the entire document, even if you only care about part of it. Section 23.3 (Parsing XML Documents with SAX 2.0) discusses an alternative approach appropriate for cases when you are dealing with very large XML documents but care about only small sections of them.
Installation and Setup
DOM is not a standard part of either Java 2 Standard Edition or the servlet and JSP APIs. So, your first step is to download the appropriate classes and configure them for use in your programs. Here is a summary of what is required.
-
Download a DOM-compliant parser. The parser provides the Java classes that follow the DOM Level 2 API as specified by the WWW Consortium. You can obtain a list of XML parsers in Java at http://www.xml.com/pub/rg/Java_Parsers. We use the Apache Xerces-J parser in this book. See http://xml.apache.org/xerces-j/. This parser also comes with the complete DOM API in Javadoc format.
-
Download the Java API for XML Processing (JAXP). This API provides a small layer on top of DOM that lets you plug in different vendor's parsers without making any changes to your basic code. See http://java.sun.com/xml/.
-
Set your CLASSPATH to include the DOM classes. In the case of Apache Xerces, you need to include xerces_install_dir\ xerces.jar. For example, for desktop applications on Windows you would do
set CLASSPATH=xerces_install_dir\xerces.jar;%CLASSPATH%
If you wanted to use DOM from servlets and JSP, you would copy the appropriate JAR file to the server's lib directory (if supported), unpack the JAR file (using jar -xvf) into the server's classes directory, or explicitly change the server's CLASSPATH, usually by modifying the server start-up script.
-
Set your CLASSPATH to include the JAXP classes. These classes are in jaxp_install_dir/jaxp.jar. For example, on Unix/Linux and the C shell, you would do
setenv CLASSPATH jaxp_install_dir/jaxp.jar:$CLASSPATH
For use from servlets and JSP, see the preceding step.
-
Bookmark the DOM Level 2 and JAXP APIs. The official DOM specification can be found at http://www.w3.org/TR/ DOM-Level-2-Core/, but the API in Javadoc format that comes with Apache Xerces is easier to read and also includes the JAXP and SAX (see Section 23.3) APIs.
-
Print the JAXP specification for your reference. Download it from http://java.sun.com/xml/jaxp-1_1-spec.pdf.
Parsing
With DOM processing, there are two high-level tasks: turning an XML document into a DOM data structure and looking through that data structure for the data that interests you. The following list summarizes the detailed steps needed to accomplish these tasks.
-
Tell the system which parser you want to use. This can be done in a number of ways: through the javax.xml.parsers.DocumentBuilderFactory system property, through jre_dir/lib/ jaxp.properties, through the J2EE Services API and the class specified in META-INF/services/javax.xml.parsers.Document1. BuilderFactory, or with a system-dependent default parser. The system property is the easiest method. For example, the following code permits users to specify the parser on the command line with the -D option to java, and uses the Apache Xerces parser otherwise.
public static void main(String[] args) { String jaxpPropertyName = "javax.xml.parsers.DocumentBuilderFactory"; if (System.getProperty(jaxpPropertyName) == null) { String apacheXercesPropertyValue = "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"; System.setProperty(jaxpPropertyName, apacheXercesPropertyValue); } ... }
-
Create a JAXP document builder. This is basically a wrapper around a specific XML parser.
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder();
Note that you can use the setNamespaceAware and set_Validating methods on the DocumentBuilderFactory to make the parser namespace aware and validating, respectively.
-
Invoke the parser to create a Document representing an XML document. You invoke the parser by calling the parse method of the document builder, supplying an input stream, URI (represented as a string), or org.xml.sax.InputSource. The Document class represents the parsed result in a tree structure.
Document document = builder.parse(someInputStream);
-
Normalize the tree. This means to combine textual nodes that were on multiple lines and to eliminate empty textual nodes.
document.getDocumentElement().normalize();
-
Obtain the root node of the tree. This returns an Element, which is a subclass of the more general Node class that represents an XML element.
Element rootElement = document.getDocumentElement();
-
Examine various properties of the node. These properties include the name of the element (getNodeName), the node type (getNodeType; compare the return value to predefined constants in the Node class), the node value (getNodeValue; e.g., for text nodes the value is the string between the element's start and end tags), the attributes used by the element's start tag (getAttributes), and the child 6. nodes (getChildNodes; i.e., the elements contained between the current element's start and end tags). You can recursively examine each of the child nodes.
-
Modify properties of the nodes. Instead of just extracting data from an XML document, you can modify the document by adding child nodes (appendChild), removing child nodes (removeChild), and changing the node's value (setNodeValue). Unfortunately, however, DOM doesn't provide a standard method of writing out a DOM structure in textual format. So, you have to either do it yourself (printing out a "<", the node name, the attribute names and values with equal signs between them and quotes around the values, a ">", etc.) or use one of the many existing packages that generate text from a DOM element.