Top Banner
JDOM Notes from Rusty Harold’s Processing XML with JAVA http://www.cafeconleche.org/ books/xmljava/chapters/ch14.html
67

JDOM Notes from Rusty Harold’s Processing XML with JAVA xmljava/chapters/ch14.html.

Dec 19, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

JDOM

Notes from Rusty Harold’s Processing XML with JAVA

http://www.cafeconleche.org/books/xmljava/chapters/ch14.html

Page 2: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

What’s wrong with DOM?

• DOM needed to be downward/backward compatible to poorly designed object modules in older browsers

• DOM was designed by committee trying to reconcile differences between Netscape, MS IE, and so on and to develop something minimally acceptable to all parties

• DOM is a cross language API defined in IDL, limited to features of languages like js and Vb – not fully OO.

• DOM needs to work for XHTLM, but also malformed HTML.

Page 3: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

JDOM is java

• JDOM was created by Jason Hunter and Brett McLaughlin of O’Reilly to fix the problems they saw with DOM.

• Interfaces (like the Node interface of DOM) are replaced by concrete classes.

• Things work the way java programmers expect them to work. (java naming conventions are used, for example).

• JDOM is to DOM as Java is to C++.

Page 4: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

JDOM is open-source

• JDOM uses the apache licensing.

• It is a tree-based API for creating, outputing, manipulating, and serializing XML documents.

• XML is represented as a tree composed of elements, attributes, comments, processing instructions, text nodes, CDATA sections, etc.

Page 5: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

JDOM uses java conventions and class libraries

• JDOM classes have equals(), toString() and hashCode() methods.

• They implement Clonable amnd Serializable interfaces.

• Children of elements are stored in java.util.List

Page 6: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

More…

• Like DOM and unlike SAX, JDOM can build a new XML tree in memory. Data can come from a database, or anywhere.

• JDOM checks data for well-formedness

• JDOM unlike SAX can modify a document and you can serialize it back out to output or elsewhere.

Page 7: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Creating XML with JDOM

• Harold follows an example of fibonaci numbers. To create the JDOM of <fibonacci/> you would write

Element element = new Element(“fibonacci”);• (DOM requires a document builder factory to

make a document, an implementation and then you can use the doc to create an element.)

• To add text to <fibonacci/> you would use, eg.,Element element = new Element(“fibonacci”);Element.setText(“8”);

Page 8: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

More…

• For the element above, you could set its index (attribute) to 6 by adding the codeelement.setAttribute(“index”,”6”);

• You can add more to an element (child elements, comments, etc) using the addContent() method:

Page 9: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

An example

• To create

<sequence><number>3</number>

<number>3</number>

</sequence>

• You need three elements (two number elements and a sequence element)

Page 10: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Example continued

Element element=new Element(“sequence”);Element first=new Element(“number”);Element second=new Element(“number”);First.setText(“3”);Second.setText(“5”);Element.addContent(first);Element.addContent(second);• What this really produces is this element: <sequence><number>3</number><number>5</

number></sequence>

Page 11: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Example continued• White space is significant in XML and thus significant in JDOM. If

you want the nicely indented element, you also need to add some strings containing the appropriate white space like this:

Element element = new Element("sequence"); Element firstNumber = new Element("number"); Element secondNumber = new Element("number");

firstNumber.setText("3"); secondNumber.setText("5"); element.addContent("\n "); element.addContent(firstNumber); element.addContent("\n "); element.addContent(secondNumber); element.addContent("\n");• If you only care about the extra white space when the document is

serialized, you can ask an XMLOutputter to insert it for you.

Page 12: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Creating XML Documents with JDOM

<?xml version="1.0"?> <GREETING>Hello JDOM!</GREETING>• Since all documents should have root elements, we’ll need to create the

root GREETING element first, then use that element to create the document:

• Element root = new Element("GREETING"); root.setText("Hello JDOM!"); Document doc = new Document(root);

• Note• Initially the Element object is not associated with any Document. It is free-

standing. This contrasts with DOM where all nodes are always part of some document. JDOM allows nodes to stand on their own if that’s useful. However, JDOM does not allow a node to be part of two documents at once. Before an Element can be transferred into a new Document it must first be detached from its old document using its detach() method.

Page 13: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Note

• Initially the Element object is not associated with any Document. It is free-standing. This contrasts with DOM where all nodes are always part of some document. JDOM allows nodes to stand on their own if that’s useful. However, JDOM does not allow a node to be part of two documents at once. Before an Element can be transferred into a new Document it must first be detached from its old document using its detach() method.

Page 14: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Writing XML Documents with JDOM

• Once you’ve created a document, you’re likely to want to serialize it to a network socket, a file, a string, or some other stream. JDOM’s org.jdom.output.XMLOutputter class does this in a standard way. You can create an XMLOutputter object with a no-args constructor and then write a document onto an OutputStream with its output() method. For example, this code fragment writes the Document object named doc onto System.out.

• XMLOutputter outputter = new XMLOutputter();• try { outputter.output(doc, System.out); } catch (IOException e)

{ System.err.println(e); }• Besides streams you can also output a document onto a

java.io.Writer. However, it’s recommended that you use an OutputStream because it’s generally not possible to determine the underlying encoding of a Writer and set the encoding declaration accordingly.

Page 15: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Writing XML fragments

• Besides documents, XMLOutputter can write elements, attributes, CDATA sections, and all the other JDOM node classes. For example, this code fragment writes an empty element named Greeting onto System.out:

XMLOutputter outputter = new XMLOutputter();

try { Element element = new Element("Greeting");

outputter.output(element, System.out); }

catch (IOException e) { System.err.println(e); }

Page 16: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Or write to a String

• This may occasionally be useful; but if you write anything other than a single Document or Element onto a stream, the result probably won’t be a well-formed XML document.

• Finally, instead of writing onto a stream or writer, you can use the outputString() methods to store an XML document or node in a String. This is often useful when passing XML data through non-XML aware systems. For example, this code fragment stores an empty element named Greeting in the String variable named hello:

XMLOutputter outputter = new XMLOutputter(); Element element = new Element("Greeting"); String hello = outputter.outputString(element);

Page 17: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

A JDOM program that produces an XML document containing Fibonacci numbersimport org.jdom.*; import org.jdom.output.XMLOutputter; import java.math.BigInteger; import java.io.IOException; public class FibonacciJDOM { public static void main(String[] args) { Element root = new Element("Fibonacci_Numbers"); BigInteger low = BigInteger.ONE; BigInteger high = BigInteger.ONE; for (int i = 1; i <= 5; i++) { Element fibonacci = new Element("fibonacci"); fibonacci.setAttribute("index", String.valueOf(i));root.addContent(fibonacci); BigInteger temp = high; high = high.add(low); low = temp; } Document doc = new Document(root); // serialize it onto System.out try { XMLOutputter serializer = new XMLOutputter(); serializer.output(doc, System.out); } catch (IOException e) { System.err.println(e); } } }

Page 18: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

The output is as follows:

• D:\books\XMLJAVA\examples\14>java FibonacciJDOM <?xml version="1.0" encoding="UTF-8"?> <Fibonacci_Numbers><fibonacci index="1">1</fibonacci><fibonacci index="2">1</fibonacci><fibonacci index="3">2</fibonacci> <fibonacci index="4">3</fibonacci><fibonacci index="5">5 </fibonacci></Fibonacci_Numbers>

Page 19: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Whitespace and cr can be set

• You can also specify the amount of indenting to use and whether or not to add line breaks as arguments to the XMLOutputter() constructor like this:

XMLOutputter serializer = new XMLOutputter(" ", true); serializer.output(doc, System.out);

Page 20: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

A database example…writing xml from javapublic static void convert(List data, OutputStream out) throws IOException { Writer wout = new OutputStreamWriter(out, "UTF8"); wout.write("<?xml

version=\"1.0\"?>\r\n"); wout.write("<Budget>\r\n");Iterator records = data.iterator(); while (records.hasNext()) { wout.write(" <LineItem>\r\n"); Map record = (Map) records.next(); Set fields = record.entrySet(); Iterator entries = fields.iterator(); while (entries.hasNext()) { Map.Entry entry = (Map.Entry) entries.next(); String name = (String) entry.getKey(); String value = (String) entry.getValue(); /* some of the values contain

ampersands and less than // signs that must be escaped */value = escapeText(value); wout.write(" <" + name + ">"); wout.write(value); wout.write("</" + name + ">\r\n"); } wout.write(" </LineItem>\r\n"); } wout.write("</Budget>\r\n"); wout.flush(); }

Page 21: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

JDOM can make this method quite a bit simpler public static void convert(List data, OutputStream out) throws

IOException { Element budget = new Element("Budget"); Iterator records = data.iterator(); while (records.hasNext()) { Element lineItem = new Element("LineItem");

budget.addContent(lineItem); Map record = (Map) records.next(); Set fields = record.entrySet(); Iterator entries = fields.iterator(); while (entries.hasNext()) { Map.Entry entry = (Map.Entry) entries.next(); String name = (String) entry.getKey(); String value = (String) entry.getValue(); Element category = new Element(name); category.setText(value);

lineItem.addContent(category); } } Document doc = new Document(budget); XMLOutputter outputter = new XMLOutputter(" ", true); outputter.output(doc, out); out.flush(); }

Page 22: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Handling DocType for the XML

Element root = new Element("Fibonacci_Numbers");

DocType type = new DocType("Fibonacci_Numbers", "fibonacci.dtd");

Document doc = new Document(root, type);

Page 23: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

You can also use the setInternalSubset() method to provide an internal DTD subset.

• As with all internal DTD subsets, this can be instead of or in addition to the external DTD subset identified by the public ID and the system ID. For example, this code fragment uses an internal DTD subset instead of an external DTD subset.

Element root = new Element("Fibonacci_Numbers"); DocType type = new DocType("Fibonacci_Numbers"); String dtd = "<!ELEMENT Fibonacci_Numbers (fibonacci*)>\n"; dtd += "<!ELEMENT fibonacci (#PCDATA)>\n"; dtd += "<!ATTLIST fibonacci index CDATA #IMPLIED>\n"; type.setInternalSubset(dtd); Document doc = new Document(root, type);

Page 24: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Reading XML with JDOM

• The rough outline for working with an existing XML document using JDOM is as follows:

1. Construct an org.jdom.input.SAXBuilder object using a simple no-args constructor

2. Invoke the builder’s build() method to build a Document object from a Reader, InputStream, URL, File, or a String containing a system ID.

3. If there’s a problem reading the document, an IOException is thrown. If there’s a problem building the document, a JDOMException is thrown.

4. Otherwise, navigate the document using the methods of the Document class, the Element class, and the other JDOM classes.

Page 25: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Recall, JDOM uses the SAX parser

• The SAXBuilder class represents the underlying XML parser. Parsing a document from a URL is straightforward. Just create a SAXBuilder object with the no-args constructor and pass the string form of the URL to its build() method. This returns a JDOM Document object. For example,

• SAXBuilder parser = new SAXBuilder(); Document doc = parser.build("http://www.cafeconleche.org/"); // work with the document...

Page 26: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

A JDOM program that checks XML documents

for well-formedness import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import java.io.IOException; public class JDOMChecker { public static void main(String[] args) { if (args.length == 0) { System.out.println("Usage: java JDOMChecker URL"); return; } SAXBuilder

builder = new SAXBuilder(); /* command line should offer URIs or file names */

try { builder.build(args[0]); /* If there are no well-formedness errors, then no exception is thrown */

System.out.println(args[0] + " is well-formed."); } // indicates a well-formedness error catch (JDOMException e) { System.out.println(args[0] + " is not well-formed."); System.out.println(e.getMessage()); } catch (IOException e) { System.out.println("Could not check " + args[0]); System.out.println(" because " + e.getMessage()); } } }

Page 27: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

A JDOM program that validates XML

documents import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import java.io.IOException; public class JDOMValidator { public static void main(String[] args) { if (args.length == 0) { System.out.println("Usage: java JDOMValidator URL"); return; }

SAXBuilder builder = new SAXBuilder(true); // ^^^^ // Turn on validation // command line should offer URIs or file namestry { builder.build(args[0]); // If there are no well-formedness or validity errors,// then no exception is thrown. System.out.println(args[0] + " is valid."); } // indicates a well-formedness or validity error catch (JDOMException e) { System.out.println(args[0] + " is not valid."); System.out.println(e.getMessage()); } catch (IOException e) { System.out.println("Could not check " + args[0]);

System.out.println(" because " + e.getMessage()); } } }

Page 28: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Note

• JDOM does not currently distinguish between validity and well-formedness errors.

Page 29: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Navigating JDOM Trees

• Once you’ve parsed a document and formed a Document object, you’ll probably want to search it to select out those parts of it your program is interested in. In JDOM, most navigation takes place through the methods of the Element class. The complete children of each Element are available as a java.util.List returned by the getContent() method. Just the child elements of each Element are available in a java.util.List returned by the getChildren() method. (Yes, the terminology is a little confusing here. This is a case where JDOM is marching out of step with the rest of the XML world. JDOM uses the word children to refer only to child elements.)

Page 30: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

remarks

• Because JDOM uses the Java Collections API to manage the tree, it is simultaneously too polymorphic (everything’s an object and must be cast to the right type before you can use it) and not polymorphic enough (there’s no useful generic interface or superclass for navigation such as DOM’s Node class.) Consequently, you’re going to find yourself doing numerous tests with instanceof and casting to the determined type. This is far and away my least favorite part of JDOM’s design. Furthermore, there’s no standard traversal API as there is in DOM to help you avoid reinventing the wheel every time you need to walk a tree or iterate a document. There is a Filter interface that can simplify some of the polymorphism and casting issues a little, but it still won’t let you walk more than one level down the tree at a time.

Page 31: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

namespaces

• I omitted coverage of namespace inclusion here

Page 32: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

A JDOM program that lists the elements used in a document

import org.jdom.*; import org.jdom.input.SAXBuilder; import java.io.IOException; import java.util.*; public class ElementLister { public static void main(String[] args) { if (args.length == 0) { System.out.println("Usage: java ElementLister URL"); return; }

SAXBuilder builder = new SAXBuilder(); try { Document doc = builder.build(args[0]); Element root = doc.getRootElement(); listChildren(root, 0); }// indicates a well-formedness error catch (JDOMException e) { System.out.println(args[0] + " is not well-

formed."); System.out.println(e.getMessage()); } catch (IOException e) { System.out.println(e); } }

Page 33: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Continuedhttp://www.cafeconleche.org/books/xmljava/chapters/ch14s08.html

• public static void listChildren(Element current, int depth) { printSpaces(depth); System.out.println(current.getName()); List children = current.getChildren(); Iterator iterator = children.iterator(); while (iterator.hasNext()) { Element child = (Element) iterator.next(); listChildren(child, depth+1); } } private static void printSpaces(int n) { for (int i = 0; i < n; i++) { System.out.print(' '); } } }

Page 34: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Output (when run on pastry.xml from previous ppt)

C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>java ElementLister pastry.xml

donuts

jelly

lemon

lemon

glazed

C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>

Page 35: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Running JDOM

• You’ll have to go find JDOM and download the zip file

• You’ll have to put the jdom.jar in a directory called org

• You’ll have to put directory org in your classpath even if it is in the java/bin directory

Page 36: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

A JDOM program that lists the nodes used in a document

• Code in notes• Output from NodeLister on pastry.xmlC:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>java NodeLister pastry.xmlDocument Comment Comment Unexpected type: class org.jdom.DocType Element: donuts Text Element: jelly Text Text Element: lemon Text Text Element: lemon Text Text Element: glazed Text Text

Page 37: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Getting attributes and namespaces

• The only pieces that are missing here are the attributes and namespaces associated with each element. These are not included by either getContent() or getChildren(). If you want them, you have to ask for them explicitly using the getAttributes(), getNamespace(), getAdditionalNamespaces(), and related methods of the Element class.

Page 38: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Talking to DOM Programs: About JDOM and DOM Elements

• A JDOM Element is not a DOM Element. Each has methods and interfaces the other does not have. You can’t pass a JDOM Element to a method expecting a DOM Element, and so on.

• The same is true for JDOM documents and DOM documents. (as well as their corresponding attribute classes/interfaces, processing instruction classes/interfaces and so on).

Page 39: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

You can convert a DOM doc into a JDOM doc

• DOMBuilder builder =new DOMBuilder();

• Org.jdom.Document jdomDocument = builder.build(domDocument);

• //now work with the jdom doc

• Going the other wy, the org.jdom.output.DOMOutputter class produces DOM docs from JDOM doc (objects).

Page 40: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

You can convert a JDOM doc into a DOM doc

• DOMOutputter converter = new DOMOutputter();

• Org.w3c.dom.Document domdoc=converter.output(jdomDoc);

• //now work with the DOM doc

• The documents are not connected or related after translation has occurred.

Page 41: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Talking to SAX Programs

• JDOM works very well with SAX parsers. SAX is an almost ideal event model for building a JDOM tree; and when the tree is complete, JDOM makes it easy to walk the tree, firing off SAX events as you go. Since SAX is so fast and memory-efficient, SAX doesn’t add a lot of extra overhead to JDOM programs.

Page 42: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Configuring SAXBuilder

• When reading a file or stream through a SAX parser, you can set various properties on the parser including the ErrorHandler, DTDHandler, EntityResolver, and any custom features or properties that are supported by the underlying SAX XMLReader. SAXBuilder includes several methods that just delegate these configurations to the underlying XMLReader:

• public void setErrorHandler(ErrorHandler errorHandler);public void setEntityResolver(EntityResolver entityResolver);public void setDTDHandler(DTDHandler dtdHandler);public void setIgnoringElementContentWhitespace(boolean ignoreWhitespace);public void setFeature(String name, boolean value);public void setProperty(String name, Object value);

Page 43: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Schema validation

• For example, suppose you want to schema validate documents before using them. This requires three additional steps beyond the norm:

1. Explicitly pick a parser class that is known to be able to schema validate such as org.apache.xerces.parsers.SAXParser (Most parsers can’t schema validate.)

2. Install a SAX ErrorHandler that reports validity errors. 3. Set the SAX feature that turns on schema validation to

true. Which feature this is depends on which parser you picked in step 1. In Xerces, it’s http://apache.org/xml/features/validation/schema and you also need to turn validation on using the standard SAX feature http://xml.org/sax/features/validation

Page 44: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

A JDOM program that schema validates documents

import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import java.io.IOException; public class JDOMSchemaValidator { public static void main(String[] args) { if (args.length == 0)

{ System.out.println("Usage: java JDOMSchemaValidator URL"); return; }

SAXBuilder builder = new SAXBuilder( "org.apache.xerces.parsers.SAXParser");

builder.setValidation(true); builder.setErrorHandler(new BestSAXChecker()); // ^^^^^^^^^^^^^^ // From Chapter 7 // turn on schema support

builder.setFeature("http://apache.org/xml/features/validation/schema", true);

// command line should offer URIs or file names try { builder.build(args[0]); } // indicates a well-formedness error catch

(JDOMException e) { System.out.println(args[0] + " is not well-formed.");

System.out.println(e.getMessage()); } catch (IOException e) { System.out.println("Could not check " +

args[0]); System.out.println(" because " + e.getMessage()); } } }

Page 45: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

A SAX program that reports all problems found in an XML document

• in notes…of next slide• from chpt 7 of Harold’s text• Program generates line numbered errors

Page 46: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

I had to remove the string from the builder constructor to get this to work

• import org.xml.sax.*; import org.xml.sax.helpers.XMLReaderFactory; import java.io.IOException; public class BestSAXChecker implements ErrorHandler { public void warning(SAXParseException exception) { System.out.println("Warning: " + exception.getMessage()); System.out.println(" at line " + exception.getLineNumber() + ", column " + exception.getColumnNumber()); System.out.println(" in entity " + exception.getSystemId()); } public void error(SAXParseException exception) { System.out.println("Error: " + exception.getMessage()); System.out.println(" at line " + exception.getLineNumber() + ", column " + exception.getColumnNumber()); System.out.println(" in entity " + exception.getSystemId()); } public void fatalError(SAXParseException exception) { System.out.println("Fatal Error: " + exception.getMessage()); System.out.println(" at line " + exception.getLineNumber() + ", column " + exception.getColumnNumber()); System.out.println(" in entity " + exception.getSystemId()); } public static void main(String[] args) { if (args.length <= 0) { System.out.println("Usage: java BestSAXChecker URL"); return; } String document = args[0]; try { XMLReader parser = XMLReaderFactory.createXMLReader(); ErrorHandler handler = new BestSAXChecker(); parser.setErrorHandler(handler); parser.parse(document); // If the document isn't well-formed, an exception has // already been thrown and this has been skipped. System.out.println(document + " is well-formed."); } catch (SAXParseException e) { System.out.print(document + " is not well-formed at "); System.out.println("Line " + e.getLineNumber() + ", column " + e.getColumnNumber() ); System.out.println(" in entity " + e.getSystemId()); } catch (SAXException e) { System.out.println("Could not check document because " + e.getMessage()); } catch (IOException e) { System.out.println( "Due to an IOException, the parser could not check " + document ); } } }

Page 47: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Got this to validate Author.xml with Author.xsd from Peltzer

• C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>java JDOMSchemaValidator Author2.xml

Page 48: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Author.xml

<Author xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="C:\Author.xsd">

<Name>Dwight Peltzer</Name> <Address>PO Box 555</Address> <City>Oyster Bay</City> <State>NY</State> <Zip>11771</Zip></Author>

Page 49: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

String representations

The JDOM toString() methods produce strings that look like these: [Document:  No DOCTYPE declaration, Root is [Element: <html 

 [Namespace: http://www.w3.org/1999/xhtml]/>]][Element: <html [Namespace: http://www.w3.org/1999/xhtml]/>][Attribute: xml:lang="en"][Text:][Attribute: type="text/css"][Attribute: rel="stylesheet"][Text: Latest Version: ][Element: <a [Namespace: http://www.w3.org/1999/xhtml]/>][Attribute: href="http://www.rddl.org/"][Text: June 16, 2002]

Page 50: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Author.xsd<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="Author"><xs:annotation> <xs:documentation></xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="Name" type="xs:string"/> <xs:element name="Address" type="xs:string"/> <xs:element name="City" type="xs:string"/> <xs:element name="State" type="xs:string"/> <xs:element name="Zip" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element></xs:schema>

Page 51: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Summary

• JDOM is a pure Java API for processing XML documents. It is more complete than either SAX (which doesn’t offer any standard way to write new XML documents) or DOM (which can manipulate XML documents but doesn’t know how to parse or serialize them). It is also much easier to use than either SAX or DOM for most tasks. It has the convenience of a pull-based tree API with DOM and the familiarity of following standard Java conventions with SAX. However, JDOM is not SAX and it is not DOM. JDOM can transfer data to and from SAX and DOM, but it is its own API, complete unto itself.

Page 52: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Summary

• JDOM uses concrete classes rather than interfaces. This means you can create instances of most of the node types just by passing an argument or two to a constructor. (The notable exception is the Namespace class which uses a factory method in order to implement the flyweight design pattern.) For instance, to create a new Element object for a number element, you simply type

• Element element = new Element("number");• Node objects do not need to be attached to any document. However, an

object can’t be part of more than one document at a time. • JDOM Document objects can also be created by parsing an existing file.

This is done by the SAXBuilder class which relies on a SAX2 parser such as Xerces. JDOM Document objects can also be built from existing DOM Document objects through the DOMBuilder class. Moving in the other direction, the XMLOutputter class can serialize a JDOM Document object onto a stream. The SAXOutputter class can feed a JDOM Document into a SAX ContentHandler, and the DOMOutputter class can convert a JDOM Document into a DOM Document.

Page 53: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

The JDOM Document classpackage org.jdom; public class Document implements Serializable, Cloneable { protected

ContentList content; protected DocType docType; public Document() public Document(Element root, DocType docType) public Document(Element root) public Document(List newContent, DocType docType) public Document(List content) public boolean hasRootElement() public Element getRootElement() public Document setRootElement(Element rootElement) public Element detachRootElement() public DocType getDocType() public

Document setDocType(DocType docType) public Document addContent(ProcessingInstruction pi) public Document addContent(Comment comment) public List getContent() public List getContent(Filter filter) public Document setContent(List newContent) public boolean removeContent(ProcessingInstruction pi) public boolean removeContent(Comment comment) // Java utility methods

public String toString() public final boolean equals(Object o) public final int hashCode() public Object clone() }

Page 54: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Inspecting elements

• TreePrinter.java in notes lists the elements and attributes, etc., following JDOM of an XML

• In notes

Page 55: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Run TreePrinter on the Author.xml

C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>java TreePrinter Author2.xmlAuthor: xsi:noNamespaceSchemaLocation="C:\Author.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

Name:

Address:

City:

State:

Zip:

Page 56: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Adding and removing children

• public Element addContent(String s);public Element addContent(Text text)    throws IllegalAddException;public Element addContent(Element element)    throws IllegalAddException;public Element addContent(ProcessingInstruction instruction)    throws IllegalAddException;public Element addContent(EntityRef ref)    throws IllegalAddException;public Element addContent(Comment comment)    throws IllegalAddException;

Page 57: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

You can run XSLTransformer (in samples directory of jdom)

• Give it xml input and xsl input and it writes html to output

• C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>

java XSLTransform catalog.xml catalog.xsl• Html is in note for this page and on next slide• Batch file contents– on one line:java org.apache.xalan.xslt.Process -INDENT 3 -IN catalog.xml -

XSL catalog.xsl -OUT catalog.html

Page 58: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Output from xalan on Transformer program

Page 59: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Using Xalan..does about the same as XSLTransformer

Page 60: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Xalan to generate html

• Here, Xalan is used with birds.xml and birds.xsl to generate birds.html. Birds.xml and birds.xsl come with Xalan

• Batch file:Java org.apache.xalan.xslt.Process -INDENT 3 -I

N birds.xml -XSL mybird.xsl -OUT birds.html

Page 61: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Running DescendantDemo to show file structure (entire output in notes)

• C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>java DescendantDemo web.xml• All content:• [Comment: <!--• <!DOCTYPE web-app• PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"• "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">• -->]• [Element: <web-app/>]• [Text:• ]• [Element: <servlet/>]• [Text:• ]• [Element: <servlet-name/>]• [Text:• snoop• ]• [Text:• ]• [Element: <servlet-class/>]• [Text:• SnoopServlet• ]• [Text:• ]• [Text:• ]• [Element: <servlet/>]• [Text:• ]• [Element: <servlet-name/>]• [Text:• file• ]

Page 62: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

DescendantDemo

• This is in the samples for JDom

• It is run on web.xml, the webapp xml file for Tomcat

Page 63: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

SAXBuilderDemo

• "Usage: java SAXBuilderDemo " +

"[XML document filename] ([expandEntities] [SAX Driver Class])");

• Builds a JDOM from SAX parser• Provides a template for setting up JDOM• Code in notes

Page 64: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

SAXBuilderDemo –some of the screenshotC:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>java SAXBuilderDemo catalog.xml<?xml version="1.0" encoding="UTF-8"?><!-- A simple XML file from Elliotte Rusty Harold's talk at SD 2000 East http://www.ibiblio.org/xml/slides/sd2000east/xslt/--><catalog> <category>Small chamber ensembles - 2-4 Players by New York Women Composers</category> <cataloging_info> <abstract>Compositions by the members of New York Women Composers</abstract>

<keyword>music publishing</keyword> <keyword>scores</keyword> <keyword>women composers</keyword> <keyword>New York</keyword> </cataloging_info> <last_updated>July 28, 1999</last_updated> <copyright>1999 New York Women Composers</copyright> <maintainer email="[email protected]" url="http://www.macfaq.com/personal.html"> <name> <first_name>Elliotte</first_name> <middle_name>Rusty</middle_name> <last_name>Harold</last_name> </name> </maintainer> <composer id="c1"> <name> <first_name>Julie</first_name> <middle_name /> <last_name>Mandel</last_name> </name> </composer> <composer id="c2"> <name>

Page 65: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Trying to get JDOM working for proj 2

• You may need this:

http://www.jdom.org/docs/apidocs/index.html

Page 66: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

Trying to get JDOM working for proj 2: printing element content from an xml with a modified DescendantDemo

• C:\PROGRA~1\JAVA\JDK15~1.0_0\BIN>java JDOMGetStructure sports.xml

• Only elements:• [Element: <root/>]• [Element: <person/>]• [Element: <FirstName/>]• [Element: <LastName/>]• [Element: <person/>]• [Element: <FirstName/>]• [Element: <LastName/>]• [Element: <person/>]• [Element: <FirstName/>]• [Element: <LastName/>]• [Element: <person/>]• [Element: <FirstName/>]• [Element: <LastName/>]• [Element: <person/>]• [Element: <FirstName/>]• [Element: <LastName/>]

Page 67: JDOM Notes from Rusty Harold’s Processing XML with JAVA  xmljava/chapters/ch14.html.

My code (with imports omitted)public class JDOMGetStructure {

public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println("Usage: java DescendantDemo [web.xml]"); return; }

SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(args[0]);System.out.println(); System.out.println("Only elements:"); Iterator itr = doc.getDescendants(new ElementFilter()); while (itr.hasNext()) { Content c = (Content) itr.next(); System.out.println(c); }}}