Easy Java/XML integration with
JDOM, Part 2 - JavaWorld July
2000
Tutorial Details:
Easy Java/XML integration with JDOM, Part 2
Easy Java/XML integration with JDOM, Part 2
By: By Jason Hunter and Brett McLaughlin
Use JDOM to create and mutate XML
n Part 1 of this series, we introduced you to JDOM, and discussed how you can use it to extract information from an existing XML data source such as a file, input stream, or URL. Additionally, we covered the core JDOM classes and explained how those classes work together to represent an XML document.
Easy Java/XML integration with JDOM: Read the whole series!
Part 1. Learn about a new API for working with XML
Part 2. Use JDOM to create and mutate XML
In this article, we tell the rest of the story and explain how you can modify XML documents or even create them from scratch. JDOM accomplishes those tasks, using standard conventions as much as possible, and lets you create, change, or move nearly every document component at runtime.
One word of warning before we begin: The JDOM API is in beta and subject to change until the 1.0 release. That release is expected within the next few months, but it may happen sooner or later, depending on when the JDOM community approves on the solidity of the design and implementation. Keep an eye on the JDOM Website for changes.
Creating a Document
In Part 1 you learned how to construct a JDOM Document from an external source:
SAXBuilder builder = new SAXBuilder(); // parameters control validation, etc
Document doc = builder.build(url);
It's also possible and even easier to construct a JDOM Document from scratch with no existing XML data store:
Element root = new Element("myRootElement");
Document doc = new Document(root);
As simple as that, you can construct an Element and a Document using that Element as the document root. At that point, normal document manipulation can occur as well:
root.setText("This is a root element");
The above code sets the root element's text content to the given string. If the Document were to output now, using XMLOutputter as discussed in Part 1, the result would be the following XML:
This is a root element
One major advantage of JDOM is that you don't need to use factories or other advanced programming models to create either the JDOM Document or constructs within the Document . You can compare that to DOM, which requires the following code to accomplish the same task: (We cannot compare it to SAX because SAX is a read-only API.)
// DOM code:
// Creating the document is vendor-specific, or requires the use of JAXP
Document doc = new org.apache.xerces.dom.DocumentImpl();
// Create the root node and its text node, using the document as a factory
Element root = myDocument.createElement("myRootElement");
Text text = myDocument.createText("This is a root element");
// Put the nodes into the document tree
root.appendChild(text);
myDocument.appendChild(root);
One thing you'll notice is that with DOM you don't have a standard way to create a Document . You have to either use implementation-specific commands or use Sun Microsystems' new JAXP API, which doesn't work with all parsers and doesn't yet support DOM2 and SAX 2.0. With JDOM, that is not an issue because JDOM documents are created through normal construction calls. You'll also notice that a DOM Node is always constructed through a factory method on its parent Document . That poses the strange chicken-and-egg problem that a DOM Element can only be created using a DOM Document object, but an XML Document should never exist without a root element! Again, with JDOM that is not an issue because elements can be created independently of documents.
Additionally, it is obvious how you move JDOM elements between documents: you simply move the children. Consider this example, where parent1 and parent2 are Element s in different JDOM documents:
// Add to first document's element
Element movable = new Element("movableRootElement");
parent1.addContent(movable);
// Remove and add to another document's element
parent1.removeContent(movable);
parent2.addContent(movable);
That straightforward move operation is possible because the JDOM Element is not created by or tied to a specific Document . In DOM, to accomplish that you must import the Element from the first DOM Document to the second, and then perform the append; a direct move fails to execute.
// DOM code:
Element movable = doc1.createElement("movable");
parent1.appendNode(movable);
// Try to append to another document's element
parent2.appendNode(movable);
// This causes an error! Incorrect document!
As you can see here, one of JDOM's core features is simplifying the way you create and modify documents.
Creating an Element
Every JDOM Document should contain, at a minimum, a root Element . Each Element , in turn, can contain as few or as many child elements as needed to represent the data in the XML document. The root Element can be passed to a Document at the time it's created, as we showed earlier:
Element root = new Element("myRootElement");
Document doc = new Document(root);
To change a Document 's root Element , you call setRootElement(Element element) on the Document :
Element newRoot = new Element("myNewRootElement");
doc.setRootElement(newRoot);
The constructor for org.jdom.Element takes the Element 's string name and can optionally take information about the Element 's namespace (which we will discuss later). This name is checked against XML 1.0 specification requirements for element naming; if the name is illegal, an IllegalNameException is thrown. To avoid having to look out for exceptions every time an Element is created, IllegalNameException extends IllegalArgumentException -- a runtime exception. Thus, you don't have to take any special actions when creating a new Element since JDOM will ensure only legal XML names are used. For example:
// This code will throw an IllegalNameException at runtime.
Element badElement = new Element("*(foo)");
That validation is handled by the org.jdom.Verifier class, which contains rules for all aspects of XML syntax. Applications can also use that class directly to ensure that a supplied name, such as in an XML editor, is correct before usage.
Element s without children most typically contain textual content. That content looks like this in XML:
Here is some textual content
In Part 1, we discussed that you can retrieve that text content with getText() :
String textualContent = element.getText();
That content can also be set through setText(String text) :
element.setText("My textual content");
JDOM simplifies the handling of special characters such as &, <, >, ', and " by dealing with them automatically. Simply set the content, using the raw string value and, upon output, the XMLOutputter class will automatically convert them to the proper XML entities that represent those characters. Of course, all builders will automatically convert them back to their traditional string values. To demonstrate, the following is perfectly legal in JDOM:
element.setText("Save cocoon.properties in /conf");
The brackets will be automatically converted to entity references when outputted through XMLOutputter :
Save cocoon.properties in <TOMCAT_HOME>/conf
Making kids
Element s often have child elements. To add a child to an element, you can use the addContent(Element element) method:
// Create a parent and two kids
Element parent = new Element("parent");
Element child1 = new Element("firstChild").setText("I'm number one");
Element child2 = new Element("secondChild").setText("I'm number two");
// Add the kids
parent.addContent(child1);
parent.addContent(child2);
The resulting XML would look like:
I'm number one
I'm number two
JDOM also supports a nesting shortcut, based on a design that may be familiar to users of other APIs such as BEA/WebLogic's htmlKona package and the Java Apache Element Construction Set (ECS). The idea is that operations on an Element return that Element for further manipulation:
Document doc = new Document(
new Element("family")
.addContent(new Element("mom"))
.addContent(new Element("dad")
.addContent("kidOfDad")));
Just be careful: It's the parenthesis location, not the indention, that determines the family tree. While that is handy in some cases, it may be confusing and error prone when constructing large JDOM Document s. If you don't want to use that feature, just ignore the returned value.
Because elements are constructed without factories, you can easily subclass the Element class, allowing for customizable elements as well as template elements. For example, if every XML document should have a common footer, you can construct that footer as a FooterElement :
root.addContent(new FooterElement());
Its contents might be something like this:
You could write the FooterElement class like this:
public class FooterElement extends Element {
public FooterElement() {
super("footer");
addContent("copyright").setText("JavaWorld 2000");
}
}
When the Element is created, it automatically adds its child elements and all their content. You can expand that idea to construct a general template for copyrights using an additional constructor:
public FooterElement(int copyrightYear) {
super("footer");
addContent("copyright").setText("JavaWorld " + copyrightYear);
}
Next year, you could then use it as follows:
root.addContent(new FooterElement(2001));
Managing the population
In Part 1, we showed you how to get an Element 's children as a Java List object:
List children = element.getChildren();
What's exciting is that the returned list of children is live and can be used to directly manage the children -- any changes to the list affect the actual children of the element. By leveraging the Java Collections API, JDOM lets the programmer change the document, u
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Easy Java/XML integration with
JDOM, Part 2 - JavaWorld July
2000
View Tutorial: Easy Java/XML integration with
JDOM, Part 2 - JavaWorld July
2000
Related
Tutorials:
XML messaging, Part
3
XML messaging, Part
3 |
Connect the
enterprise with the JCA, Part 1
Connect the
enterprise with the JCA, Part 1 |
Use XML data binding to do your
laundry
Use XML data binding to do your
laundry |
Use Web services
to integrate Web applications with
EISs
Use Web services
to integrate Web applications with
EISs |
I want my AOP!,
Part 2
I want my AOP!,
Part 2 |
Discover and publish Web services with JAXR
Discover and publish Web services with JAXR |
Create your own type 3 JDBC driver, Part 2
Create your own type 3 JDBC driver, Part 2 |
Business process
automation
made easy with
Java, Part 1
Business process
automation
made easy with
Java, Part 1 |
Business process
automation
made easy with
Java, Part 2
Business process
automation
made easy with
Java, Part 2 |
Sun boosts
Sun boosts enterprise Java |
Update distributed applications
Update distributed applications |
Get the inside
track on J2EE architect certification
Get the inside
track on J2EE architect certification |
The Java Web Services Tutorial
This tutorial is a beginner\'s guide to developing Web services and Web applications using the Java Web Services Developer Pack (Java WSDP). |
Very
interesting
Very
interesting |
Maybe the future UI design of choice
Maybe the future UI design of choice |
Java Development on Eclipse, Part 2
Java Development on Eclipse, Part 2
Editor's note: In part one of this two-part series of excerpts from Eclipse, author Steve Holzner provided examples of how Eclipse makes it easier to create Java code from scratch. Continuing in that vein, in this we |
JDBC scripting, Part 2
JDBC scripting, Part 2
Programming and Java scripting in JudoScript
Summary
JudoScript is a rich functional scripting language, and an easy and powerful general programming and Java scripting language.
JudoScript's power comes from its synergy of |
The JavaTM Web Services Tutorial
A beginner's guide to developing Web services and Web applications on the Java Web Services Developer Pack |
Biological Databases Links
Biological Databases Links
Biological Databases
Biological Databases are like any other databases. Biological Database contains the sequence data of DNA, RNA etc.. These database are organized for optimal retrieval and analysis.
Here are the |
New Technical Articles: 64-bit Programming on Solaris 10 OS for x86 Platforms
Four technical articles describe the new Sun Studio 10 software's 64-bit programming features on the Solaris 10 OS for x86 and AMD64 platforms. Important issues regarding the AMD64 ABI (Application Binary Interface), debugging, migration to 64-bits, and p |
|
|
|