apache > ws.apache
Apache Muse
 

Apache Muse - Create XML Fragments with XmlUtils

The Muse runtime does a lot of XML processing in almost all of its tasks, and much of that processing power comes from a class called org.apache.muse.util.xml.XmlUtils. This class provides a long list of well-documented static methods for reading and writing XML fragments. And while the Muse framework and tooling try to help you avoid processing DOM trees as part of your resource implementation, the fact is that sometimes you just have to roll up your sleeves and tackle the XML yourself.

The XmlUtils class makes using the DOM API much easier by reducing the amount of boilerplate code you have to write. This how-to will show you how to create XML documents and/or fragments that can be used with Muse APIs or packaged as part of SOAP messages.

Note
The XmlUtils class also has methods for parsing and filtering XML.

The most important thing to keep in mind when programming against the DOM API is that that the DOM API uses org.w3c.dom.Document as both the container of nodes in an XML document and as the factory for node creation. It is not necessary for XML fragments to be appended to a document, but they will always have an "owner document" that created them. Two nodes that were created by different documents (factories) cannot be combined into a larger XML fragment until one of them is "imported" by the other's owner document.

Because keeping track of these owner documents is a pain, the methods in the XmlUtils class are designed so that each task can be completed by either a) providing the DOM document that will be used for the creation of nodes, or b) using the "default" document maintained by XmlUtils. The latter is an empty DOM document whose sole purpose is to create new nodes. This makes the XmlUtils class more efficient because it does not have to create a DocumentBuilderFactory, DocumentBuilder, and Document every time it wants to create new nodes.

The default document (factory) is named XmlUtils.EMPTY_DOC. You will not have to refer to it directly, but it is useful to understand its purpose, as recorded in the JavaDoc: This should not be used by callers that want to build new fragments and attach them to a Document - this is merely a scratch pad for creating new DOM components without having to make a new Document each time. There are no guarantees as to the content of the empty Document, but you should never append children to it.

XML fragments are created with an overloaded method named createElement(). The implementation of this method will use XmlUtil's various conversion methods to turn Java objects into XML. The versions of this method without a org.w3c.dom.Document parameter will use the default Document (EMPTY_DOC) as the node factory. You should read the JavaDoc for each of the methods to understand the details of its behavior.

Here is some sample code that illustrates the creation of XML fragments:

import java.net.URI;
import javax.xml.namespace.QName;

import org.w3c.dom.*;

import org.apache.muse.util.xml.XmlUtils;

...

QName rootName = new QName("http://ws.apache.org/muse/test", "RootElement", "test");
QName firstName = new QName("http://ws.apache.org/muse/test", "FirstChild", "test");
QName secondName = new QName("http://ws.apache.org/muse/test", "SecondChild", "test");

URI firstValue = URI.create("http://ws.apache.org/muse/some/important/URI");
String secondValue = "This is an important message.";

//
// Create the root element of the fragment
//
Element root = XmlUtils.createElement(rootName);

//
// Add a <FirstChild/> element under <RootElement/>
//
Element firstChild = XmlUtils.createElement(firstName, firstValue);
root.appendChild(firstChild);

//
// Here is another way of adding the first child
//
XmlUtils.setElement(root, firstName, firstValue);

//
// Add a <SecondChild/> element under <RootElement/>
//
Element secondChild = XmlUtils.createElement(secondName, secondValue);
root.appendChild(secondChild);

//
// Here is another way of adding the second child
//
Element secondChild = XmlUtils.createElement(secondName);
XmlUtils.setElementText(secondChild, secondValue);
root.appendChild(secondChild);

Note that for every version of createElement() shown here, there is an equivalent version that takes a org.w3c.dom.Document parameter so that you can specify which document will be used as the node factory. All nodes created with this document will return a reference to it when you invoke the getOwnerDocument() on the org.w3c.dom.Node objects.

Of particular interest is the version of createElement() that takes four parameters. This method gives you the most control over adding XML fragments to each other, including how one XML fragment should be embedded inside the other. Here is some sample code that illustrates the use of this function:

//
// This code will append the <SecondChild/> and its contents under
// the <FirstChild/>, all using the same DOM Document. You can
// substitute XmlUtils.EMPTY_DOC for any other DOM Document object.
//
Element secondChild = XmlUtils.createElement(secondName, secondValue);
Element firstChild = XmlUtils.createElement(XmlUtils.EMPTY_DOC, firstName, secondChild, false);

Finally, the XmlUtils class provides methods for creating DOM Documents as well as Elements. The createDocument() methods allow you to create XML documents from a variety of sources.

Note
There is a separate how-to for loading XML from a file.

You can create a brand new DOM Document without all of the JAXP boilerplate with the following code:

Document doc = XmlUtils.createDocument();