Book Image

Processing XML documents with Oracle JDeveloper 11g

Book Image

Processing XML documents with Oracle JDeveloper 11g

Overview of this book

XML is an open standard for creating markup languages and exchanging structured documents and data over the Internet. JDeveloper 11g presents an effective, quick, and easy-to-use means of processing XML documents. Inspired by the author's previous XML articles for the Oracle community, this expanded hands-on tutorial guides newcomers and intermediate users through JDeveloper 11g and XML document development. It offers up-to-date information on working with the latest version of JDeveloper, and brand new information on JAXB 2.0 support in JDeveloper 11g. Filled with illustrations, explanatory tables, and comprehensive instructions, this book walks the reader through the wide assortment of JDeveloper's capabilities. Oracle's JDeveloper 11g is an Integrated Development Environment that provides a visual and declarative approach to application development. Over the course of 14 chapters, readers will get hands-on with JDeveloper as the comprehensive and self-contained tutorials provide clear instruction on the key XML tasks that JDeveloper can accomplish. Filled with practical information and illustrated examples, this book shows the reader how to create, parse, and store XML documents quickly, as well as providing step-by-step instructions on how to construct an XML schema and use the schema to validate an XML document. Oracle's XML Developer Kit (XDK) offers a set of components, tools, and utilities for developing XML-based applications, and developers will find the detailed XDK coverage invaluable. Later chapters are given over to using XPath, transforming XML with XSLT, and using the JSTL XML Tag Library. Moving through the book, a chapter on the JAXB 2.0 API shows you how to bind, marshal and unmarshal XML documents, before we finally delve into comparing XML documents, and converting them into PDF and Excel formats. In all, this book will enable the reader to gain a good and wide-ranging understanding of what JDeveloper has to offer for XML processing.
Table of Contents (19 chapters)
Processing XML documents with Oracle JDeveloper 11g
Credits
About the Author
About the Reviewers
Preface

Parsing an XML document with the SAX API


SAX parsing is based on the push model in which events are generated by an SAX parser and a document handler receives notification of the events. The SAX parsing model is faster than DOM parsing, but is limited in its scope to generating parsing events, without any provision for navigating the nodes or retrieving nodes with XPath. In this section, we shall parse the example XML document with a SAX parser and output the events generated by the parser. The SAX parsing application will be developed in JDeveloper in the Java application SAXParserApp.java. First, import the oracle.xml.jaxp package:

import oracle.xml.jaxp.*;

An SAX parsing application typically extends the DefaultHandler class, which has event-notification methods for the parse events. The DefaultHandler class implements the ErrorHandler interface. A DefaultHandler object may also be used for error handling.

Creating the factory

Create a JXSAXParserFactory object with the static method newInstance(). The newInstance() method returns a SAXParserFactory object that may be cast to JXSAXParserFactory as the JXSAXParserFactory class extends the SAXParserFactory class. Why cast, you might ask? We are using Oracle XDK 11g's implementation classes for various standard interfaces and abstract classes.

JXSAXParserFactory factory = (JXSAXParserFactory) JXSAXParserFactory.newInstance();

The factory object is used to obtain a SAX parser that may be used to parse an XML document.

Parsing the XML document

Create a SAXParser object from the factory object with the newSAXParser() method. As class JXSAXParser extends the SAXParser class, a SAXParser object may be cast to JXSAXParser:

JXSAXParser saxParser = (JXSAXParser) factory.newSAXParser();

Create an InputStream for the XML document to parse, and parse the XML document with one of the parse() methods in the SAXParser class. The parse methods take an XML document in the form of InputSource, InputStream, URI, or File, and an event handler such as the DefaultHandler.

InputStream input = new FileInputStream(new File("catalog.xml"));
saxParser.parse(input, this);

The DefaultHandler class provides the parsing event notification methods and error handling methods. Event notification and error handling methods may be overridden in the SAX parsing application for application-specific events and error handling. Some of the event notification methods in the DefaultHandler class are listed in the following table:

Method Name

Description

startDocument()

Receive notification of the start of the document. The startDocument method is invoked before the XML declaration.

endDocument()

Receive notification of the end of the document. The endDocument method is invoked after the closing tag of the root element.

startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes)

Receive notification of the start of an element. The URI parameter specifies the namespace URI. LocalName specifies the element local name, which is the element name without the prefix. QName specifies the qualified element name; element name with prefix. The attributes parameter specifies the list of attributes in an element.

endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName)

Receive notification of the end of an element.

characters(char[] ch, int start, int length)

Receive notification of the character data (text).

ignorableWhitespace(char[] ch, int start, int length)

Receive notification of the ignorable whitespace in an element.

notationDecl(String name, String publicId, String systemId)

Receive notification of a notation.

processingInstruction(String target, String data)

Receive notification of a processing instruction.

unparsedEntityDecl(String name, String publicId, String systemId, String notationName)

Receive notification of an unparsed entity declaration. Unparsed entity declarations are entities that refer to non-XML data that a parser does not have to parse. For example:

<!ENTITY banner SYSTEM "http://www.logos.net/logo.jpg" NDATA jpeg>

<!NOTATION jpeg PUBLIC "jpeg viewer">

skippedEntity(String name)

Receive notification of a skipped entity. Skipped entity notifications may be received when using a non-validating parser, which is not required to parse an external DTD and thus not required to resolve all entity references. Entity references that are not resolved are skipped entities.

startPrefixMapping(String prefix, String uri)

Receive notification of the start of a namespace mapping. An example of a namespace mapping is as follows:

xmls:xsd="http://www.w3.org/2001/XMLSchema"

endPrefixMapping(String prefix)

Receive notification of the end of a namespace mapping.

In the SAXParserApp.java application, some of the notification methods are overridden to output the event type, element name, element attributes, and element text. For example, the attributes represented by the Attributes object in the startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes atts) method may be iterated to output the attribute name, namespace URI, and attribute value:

for (int i = 0; i < atts.getLength(); i++) {
System.out.println("Attribute QName:" +atts.getQName(i));
System.out.println("Attribute Local Name:"+ atts.getLocalName(i));
System.out.println("Attribute Namespace URI:" + atts.getURI(i));
System.out.println("Attribute Value:"+atts.getValue(i));
}

The error handler methods in DefaultHandler may also be overridden. In the SAXParserApp.java application, the error handler methods are overridden to output the error message. We shall demonstrate error handling in a SAX parsing application with an example. Error handler methods in the DefaultHandler class are listed in the following table:

Method Name

Description

error(SAXParseException exception)

Receives notification of a recoverable error

fatalError(SAXParseException exception)

Receives notification of a non-recoverable error

warning(SAXParseException exception)

Receives notification of a warning

Running the Java application

The SAXParserApp.java application is listed as follows with notes about the different sections of the Java class:

  1. 1. Add the package and import statements.

    package xmlparser;
    import oracle.xml.jaxp.*;
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.SAXParseException;
    import org.xml.sax.helpers.DefaultHandler;
    import java.io.*;
    import javax.xml.parsers.ParserConfigurationException;
    
  2. 2. Next, we add the Java class SAXParserApp.

    public class SAXParserApp extends DefaultHandler {
    
  3. 3. Next, we add a method parseXMLDocument to parse the XML document, catalog.xml.

    public void parseXMLDocument() {
    try {
    JXSAXParserFactory factory = (JXSAXParserFactory) JXSAXParserFactory.newInstance();
    JXSAXParser saxParser = (JXSAXParser) factory.newSAXParser();
    InputStream input = new FileInputStream(new File("catalog.xml"));
    saxParser.parse(input, this);
    }catch (ParserConfigurationException e) {
    System.err.println(e.getMessage());
    }catch (FileNotFoundException e) {
    System.err.println(e.getMessage());
    }catch (IOException e) { System.err.println(e.getMessage());
    }catch (SAXException e) { System.err.println(e.getMessage());
    }
    }
    
  4. 4. The startDocument event notification method notifies about the start of an XML document.

    public void startDocument() throws SAXException {
    System.out.println("SAX Event : Start Document");
    }
    
  5. 5. The endDocument event notification method notifies about the end of an XML document.

    public void endDocument() throws SAXException {
    System.out.println("SAX Event : End Document");
    }
    
  6. 6. The startElement event notification method notifies about the start of an element.

    public void startElement(java.lang.String namespaceURI,
    java.lang.String localName, java.lang.String qName, Attributes atts)throws SAXException {
    System.out.println("SAX Event : Start Element");
    System.out.println("Element QName:" + qName);
    System.out.println("Element Local Name:" + localName);
    System.out.println("Element Namespace URI:"+namespaceURI);
    for (int i = 0; i < atts.getLength(); i++) {
    System.out.println("Attribute QName:"+atts.getQName(i));
    System.out.println("Attribute Local Name:"+ atts.getLocalName(i));
    System.out.println("Attribute Namespace URI:"+ atts.getURI(i));
    System.out.println("Attribute Value:"+atts.getValue(i));
    }
    }
    
  7. 7. The event notification method endElement notifies about the end of an element.

    public void endElement(java.lang.String namespaceURI,
    java.lang.String localName, java.lang.String qName)
    throws SAXException {
    System.out.println("SAX Event : End Element");
    System.out.println("Element QName:" + qName);
    }
    
  8. 8. The event notification method characters notifies about character text.

    public void characters(char[] ch, int start, int length)
    throws SAXException {
    System.out.println("SAX Event : Text");
    String text = new String(ch, start, length).trim();
    if (text.length() > 0) {
    System.out.println("Text:" + text);
    }
    }
    
  9. 9. Here, the error handling method error handles recoverable errors.

    public void error(SAXParseException e) throws SAXException {
    System.err.println("Error:" + e.getMessage());
    }
    
  10. 10. The error handling method fatalError handles non-recoverable errors.

    public void fatalError(SAXParseException e) throws SAXException {
    System.err.println("Fatal Error:" + e.getMessage());
    }
    
  11. 11. The error handling method warning handles parser warnings.

    public void warning(SAXParseException e) throws SAXException {
    System.out.println("Warning:" + e.getMessage());
    }
    
  12. 12. Finally, add the main method. In the main method, create an instance of the SAXParserApp class and invoke the parseXMLDocument method.

    public static void main(String[] argv) {
    SAXParserApp saxParser = new SAXParserApp();
    saxParser.parseXMLDocument();
    }
    }
    
    
  13. 13. To run the SAXParserApp.java application in JDeveloper, right-click on the SAXParserApp.java node in Application Navigator, and select Run.

The output from the SAX parsing application lists the SAX events, elements, and attributes in the parsed XML document.

The complete output from the SAX parsing application is listed as follows:

SAX Event : Start Document
SAX Event : Start Element
Element QName:catalog
Element Local Name:catalog
Element Namespace URI:
SAX Event : Text
SAX Event : Start Element
Element QName:journal:journal
Element Local Name:journal
Element Namespace URI:http://xdk.com/catalog/journal
Attribute QName:journal:title
Attribute Local Name:title
Attribute Namespace URI:http://xdk.com/catalog/journal
Attribute Value:Oracle Magazine
Attribute QName:journal:publisher
Attribute Local Name:publisher
Attribute Namespace URI:http://xdk.com/catalog/journal
Attribute Value:Oracle Publishing
Attribute QName:journal:edition
Attribute Local Name:edition
Attribute Namespace URI:http://xdk.com/catalog/journal
Attribute Value:March-April 2008
Attribute QName:xmlns:journal
Attribute Local Name:journal
Attribute Namespace URI:http://www.w3.org/2000/xmlns/
Attribute Value:http://xdk.com/catalog/journal
SAX Event : Text
SAX Event : Start Element
Element QName:journal:article
Element Local Name:article
Element Namespace URI:http://xdk.com/catalog/journal
Attribute QName:journal:section
Attribute Local Name:section
Attribute Namespace URI:http://xdk.com/catalog/journal
Attribute Value:Oracle Developer
SAX Event : Text
SAX Event : Start Element
Element QName:journal:title
Element Local Name:title
Element Namespace URI:http://xdk.com/catalog/journal
SAX Event : Text
Text:Declarative Data Filtering
SAX Event : End Element
Element QName:journal:title
SAX Event : Text
SAX Event : Start Element
Element QName:journal:author
Element Local Name:author
Element Namespace URI:http://xdk.com/catalog/journal
SAX Event : Text
Text:Steve Muench
SAX Event : End Element
Element QName:journal:author
SAX Event : Text
SAX Event : End Element
Element QName:journal:article
SAX Event : Text
SAX Event : End Element
Element QName:journal:journal
SAX Event : Text
SAX Event : Start Element
Element QName:journal
Element Local Name:journal
Element Namespace URI:
Attribute QName:title
Attribute Local Name:title
Attribute Namespace URI:
Attribute Value:Oracle Magazine
Attribute QName:publisher
Attribute Local Name:publisher
Attribute Namespace URI:
Attribute Value:Oracle Publishing
Attribute QName:edition
Attribute Local Name:edition
Attribute Namespace URI:
Attribute Value:September-October 2008
SAX Event : Text
SAX Event : Start Element
Element QName:article
Element Local Name:article
Element Namespace URI:
Attribute QName:section
Attribute Local Name:section
Attribute Namespace URI:
Attribute Value:FEATURES
SAX Event : Text
SAX Event : Start Element
Element QName:title
Element Local Name:title
Element Namespace URI:
SAX Event : Text
Text:Share 2.0
SAX Event : End Element
Element QName:title
SAX Event : Text
SAX Event : Start Element
Element QName:author
Element Local Name:author
Element Namespace URI:
SAX Event : Text
Text:Alan Joch
SAX Event : End Element
Element QName:author
SAX Event : Text
SAX Event : End Element
Element QName:article
SAX Event : Text
SAX Event : End Element
Element QName:journal
SAX Event : Text
SAX Event : End Element
Element QName:catalog
SAX Event : End Document

To demonstrate error handling, add an error in the example XML document. For example, remove a </journal> node, as we did earlier. Run the SAXParserApp.java application in JDeveloper. An error message gets outputted:

Fatal Error:<Line 15, Column 10>: XML-20121: (Fatal Error) End tag does not match start tag 'journal'.