Flexible XML framework for Java providing comprehensive XML processing capabilities
—
The core DOM4J API defines the fundamental interfaces and classes for working with XML documents. This section covers the Node hierarchy, Document interface, Element interface, and Attribute interface that form the foundation of DOM4J's tree-based XML processing model.
The Node interface is the root of the DOM4J node hierarchy and defines polymorphic behavior for all node types in the XML tree.
import org.dom4j.Node;public interface Node {
short ANY_NODE = 0;
short ELEMENT_NODE = 1;
short ATTRIBUTE_NODE = 2;
short TEXT_NODE = 3;
short CDATA_SECTION_NODE = 4;
short ENTITY_REFERENCE_NODE = 5;
short PROCESSING_INSTRUCTION_NODE = 7;
short COMMENT_NODE = 8;
short DOCUMENT_NODE = 9;
short DOCUMENT_TYPE_NODE = 10;
short NAMESPACE_NODE = 13;
short UNKNOWN_NODE = 14;
short MAX_NODE_TYPE = 14;
}public interface Node extends Cloneable {
// Parent and document relationships
boolean supportsParent();
Element getParent();
void setParent(Element parent);
Document getDocument();
void setDocument(Document document);
// Node properties
boolean isReadOnly();
boolean hasContent();
String getName();
void setName(String name);
String getText();
void setText(String text);
String getStringValue();
// Path and identification
String getPath();
String getPath(Element context);
String getUniquePath();
String getUniquePath(Element context);
// Serialization
String asXML();
void write(Writer writer) throws IOException;
// Type information
short getNodeType();
String getNodeTypeName();
// Tree manipulation
Node detach();
// XPath support
List<Node> selectNodes(String xpathExpression);
Object selectObject(String xpathExpression);
Node selectSingleNode(String xpathExpression);
String valueOf(String xpathExpression);
Number numberValueOf(String xpathExpression);
boolean matches(String xpathExpression);
XPath createXPath(String xpathExpression) throws InvalidXPathException;
Node asXPathResult(Element parent);
// Visitor pattern
void accept(Visitor visitor);
// Object support
Object clone();
}// Check node type
Node node = element.selectSingleNode("child");
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element childElement = (Element) node;
// Process as element
}
// Get node path for debugging
String path = node.getPath(); // Returns XPath-like path
String uniquePath = node.getUniquePath(); // Returns unique path with indices
// XPath operations on any node
List<Node> matches = node.selectNodes(".//text()");
String value = node.valueOf("@attribute");
boolean hasMatch = node.matches("self::element[@attr]");
// Visitor pattern for type-safe processing
node.accept(new VisitorSupport() {
public void visit(Element element) {
System.out.println("Found element: " + element.getName());
}
public void visit(Text text) {
System.out.println("Found text: " + text.getText());
}
});Branch defines common behavior for nodes that can contain child nodes (Elements and Documents).
import org.dom4j.Branch;public interface Branch extends Node {
// Node access
Node node(int index) throws IndexOutOfBoundsException;
int indexOf(Node node);
int nodeCount();
Element elementByID(String elementID);
// Content management
List<Node> content();
Iterator<Node> nodeIterator();
void setContent(List<Node> content);
void appendContent(Branch branch);
void clearContent();
// Processing instructions
List<ProcessingInstruction> processingInstructions();
List<ProcessingInstruction> processingInstructions(String target);
ProcessingInstruction processingInstruction(String target);
void setProcessingInstructions(List<ProcessingInstruction> listOfPIs);
boolean removeProcessingInstruction(String target);
// Element creation
Element addElement(String name);
Element addElement(QName qname);
Element addElement(String qualifiedName, String namespaceURI);
// Content addition
void add(Node node);
void add(Comment comment);
void add(Element element);
void add(ProcessingInstruction pi);
// Content removal
boolean remove(Node node);
boolean remove(Comment comment);
boolean remove(Element element);
boolean remove(ProcessingInstruction pi);
// Normalization
void normalize();
}// Work with any Branch (Document or Element)
Branch branch = document.getRootElement();
// Add various node types
branch.add(DocumentHelper.createComment("A comment"));
branch.add(DocumentHelper.createText("Some text"));
Element newChild = branch.addElement("child");
// Iterate through content
for (Iterator<Node> iter = branch.nodeIterator(); iter.hasNext();) {
Node node = iter.next();
processNode(node);
}
// Content management
List<Node> content = branch.content();
branch.clearContent();
branch.appendContent(otherBranch);
// Processing instructions
branch.add(DocumentHelper.createProcessingInstruction("xml-stylesheet",
"type=\"text/xsl\" href=\"style.xsl\""));
List<ProcessingInstruction> pis = branch.processingInstructions();The Document interface represents an XML document and extends Branch to include document-specific functionality.
import org.dom4j.Document;public interface Document extends Branch {
// Root element management
Element getRootElement();
void setRootElement(Element rootElement);
// Document-level content
Document addComment(String comment);
Document addProcessingInstruction(String target, String text);
Document addProcessingInstruction(String target, Map<String, String> data);
Document addDocType(String name, String publicId, String systemId);
// Document type
DocumentType getDocType();
void setDocType(DocumentType docType);
// Entity resolution
EntityResolver getEntityResolver();
void setEntityResolver(EntityResolver entityResolver);
// Encoding
String getXMLEncoding();
void setXMLEncoding(String encoding);
}// Create and configure document
Document document = DocumentHelper.createDocument();
document.setXMLEncoding("UTF-8");
// Add document-level processing instruction
document.addProcessingInstruction("xml-stylesheet",
Map.of("type", "text/xsl", "href", "transform.xsl"));
// Add DOCTYPE declaration
document.addDocType("html", "-//W3C//DTD XHTML 1.0 Strict//EN",
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
// Set root element
Element root = DocumentHelper.createElement("root");
document.setRootElement(root);
// Document information
String encoding = document.getXMLEncoding();
DocumentType docType = document.getDocType();
Element rootElement = document.getRootElement();
// Document-wide XPath queries
List<Element> allElements = document.selectNodes("//element");
Element specificElement = (Element) document.selectSingleNode("//element[@id='123']");The Element interface defines XML element behavior, including namespace support, attributes, child nodes, and text content.
import org.dom4j.Element;
import org.dom4j.QName;
import org.dom4j.Namespace;
import org.dom4j.Attribute;public interface Element extends Branch {
// QName and namespace access
QName getQName();
void setQName(QName qname);
Namespace getNamespace();
QName getQName(String qualifiedName);
// Namespace resolution
Namespace getNamespaceForPrefix(String prefix);
Namespace getNamespaceForURI(String uri);
List<Namespace> getNamespacesForURI(String uri);
String getNamespacePrefix();
String getNamespaceURI();
String getQualifiedName();
// Namespace declarations
List<Namespace> additionalNamespaces();
List<Namespace> declaredNamespaces();
}public interface Element extends Branch {
// Content builders (return this Element for chaining)
Element addAttribute(String name, String value);
Element addAttribute(QName qName, String value);
Element addComment(String comment);
Element addCDATA(String cdata);
Element addEntity(String name, String text);
Element addNamespace(String prefix, String uri);
Element addProcessingInstruction(String target, String text);
Element addProcessingInstruction(String target, Map<String, String> data);
Element addText(String text);
}public interface Element extends Branch {
// Attribute collections
List<Attribute> attributes();
void setAttributes(List<Attribute> attributes);
int attributeCount();
Iterator<Attribute> attributeIterator();
// Attribute access
Attribute attribute(int index);
Attribute attribute(String name);
Attribute attribute(QName qName);
// Attribute values
String attributeValue(String name);
String attributeValue(String name, String defaultValue);
String attributeValue(QName qName);
String attributeValue(QName qName, String defaultValue);
}public interface Element extends Branch {
// Child element access
Element element(String name);
Element element(QName qName);
List<Element> elements();
List<Element> elements(String name);
List<Element> elements(QName qName);
// Element iteration
Iterator<Element> elementIterator();
Iterator<Element> elementIterator(String name);
Iterator<Element> elementIterator(QName qName);
// Element properties
boolean isRootElement();
boolean hasMixedContent();
boolean isTextOnly();
// Element operations
void appendAttributes(Element element);
Element createCopy();
Element createCopy(String name);
Element createCopy(QName qName);
// Element text content
String elementText(String name);
String elementText(QName qname);
String elementTextTrim(String name);
String elementTextTrim(QName qname);
// XPath result access
Node getXPathResult(int index);
}// Create element with namespace
Namespace ns = Namespace.get("prefix", "http://example.com/ns");
Element root = DocumentHelper.createElement(QName.get("root", ns));
// Builder pattern for content creation
Element person = root.addElement("person")
.addAttribute("id", "123")
.addAttribute("active", "true")
.addText("John Doe");
// Add namespaced child element
Element address = person.addElement(QName.get("address", ns))
.addText("123 Main St");
// Attribute access
String id = person.attributeValue("id");
String active = person.attributeValue("active", "false"); // with default
Attribute idAttr = person.attribute("id");
// Child element access
Element addressElement = person.element("address");
List<Element> children = person.elements();
List<Element> addressElements = person.elements("address");
// Element navigation
for (Iterator<Element> iter = root.elementIterator(); iter.hasNext();) {
Element child = iter.next();
System.out.println("Child: " + child.getName());
}
// Element text content
String personName = person.getText();
String addressText = person.elementText("address");
String trimmedAddress = person.elementTextTrim("address");
// Element properties
boolean isRoot = root.isRootElement(); // true
boolean hasText = person.isTextOnly(); // true if only text content
boolean hasMixed = person.hasMixedContent(); // true if text and elements
// Namespace operations
String namespaceURI = root.getNamespaceURI();
String prefix = root.getNamespacePrefix();
Namespace elementNS = root.getNamespace();
List<Namespace> declared = root.declaredNamespaces();
// Element copying
Element copy = person.createCopy();
Element namedCopy = person.createCopy("employee");The Attribute interface represents XML attributes with name, optional namespace, and value.
import org.dom4j.Attribute;
import org.dom4j.QName;
import org.dom4j.Namespace;public interface Attribute extends Node {
// Name and namespace
QName getQName();
Namespace getNamespace();
void setNamespace(Namespace namespace);
String getNamespacePrefix();
String getNamespaceURI();
String getQualifiedName();
// Value access
String getValue();
void setValue(String value);
// Data storage
Object getData();
void setData(Object data);
}// Create element with attributes
Element element = DocumentHelper.createElement("product");
element.addAttribute("id", "P123");
element.addAttribute("price", "29.99");
// Access attributes
Attribute idAttr = element.attribute("id");
String id = idAttr.getValue();
String name = idAttr.getName();
QName qname = idAttr.getQName();
// Namespaced attributes
Namespace ns = Namespace.get("app", "http://myapp.com/");
element.addAttribute(QName.get("status", ns), "active");
Attribute statusAttr = element.attribute(QName.get("status", ns));
String namespaceURI = statusAttr.getNamespaceURI(); // "http://myapp.com/"
String prefix = statusAttr.getNamespacePrefix(); // "app"
String qualifiedName = statusAttr.getQualifiedName(); // "app:status"
// Attribute manipulation
statusAttr.setValue("inactive");
idAttr.setData(Integer.valueOf(123)); // Store typed data
// Iterate through all attributes
for (Iterator<Attribute> iter = element.attributeIterator(); iter.hasNext();) {
Attribute attr = iter.next();
System.out.println(attr.getName() + " = " + attr.getValue());
}
// Get attribute list
List<Attribute> attributes = element.attributes();
int attributeCount = element.attributeCount();QName represents qualified names with local name and namespace. It's an immutable value object used throughout DOM4J for namespace-aware operations.
import org.dom4j.QName;
import org.dom4j.Namespace;
import org.dom4j.DocumentFactory;public class QName {
// Factory methods
public static QName get(String name);
public static QName get(String name, Namespace namespace);
public static QName get(String name, String prefix, String uri);
public static QName get(String qualifiedName, String uri);
}public class QName {
// Name access
public String getName();
public String getQualifiedName();
// Namespace access
public Namespace getNamespace();
public String getNamespacePrefix();
public String getNamespaceURI();
// Factory access
public DocumentFactory getDocumentFactory();
public void setDocumentFactory(DocumentFactory documentFactory);
}// Create QNames
QName simpleName = QName.get("element");
QName namespacedName = QName.get("element",
Namespace.get("ns", "http://example.com/"));
QName withPrefix = QName.get("element", "ns", "http://example.com/");
QName fromQualified = QName.get("ns:element", "http://example.com/");
// Access QName properties
String localName = namespacedName.getName(); // "element"
String qualified = namespacedName.getQualifiedName(); // "ns:element"
String uri = namespacedName.getNamespaceURI(); // "http://example.com/"
String prefix = namespacedName.getNamespacePrefix(); // "ns"
Namespace namespace = namespacedName.getNamespace();
// Use QNames with elements and attributes
Element element = DocumentHelper.createElement(namespacedName);
element.addAttribute(QName.get("id"), "123");
// QName equality and hashing
QName qname1 = QName.get("element", "ns", "http://example.com/");
QName qname2 = QName.get("element", "ns", "http://example.com/");
boolean equal = qname1.equals(qname2); // true - QNames are cachedNamespace is a flyweight class representing XML namespaces that can be shared among nodes.
import org.dom4j.Namespace;public class Namespace {
// Predefined namespaces
public static final Namespace XML_NAMESPACE; // XML namespace
public static final Namespace NO_NAMESPACE; // Empty namespace
// Factory methods
public static Namespace get(String prefix, String uri);
public static Namespace get(String uri); // Creates with empty prefix
}public class Namespace {
// Property access
public String getPrefix();
public String getURI();
}// Create namespaces
Namespace defaultNS = Namespace.get("http://example.com/default");
Namespace prefixedNS = Namespace.get("app", "http://example.com/app");
// Predefined namespaces
Namespace xmlNS = Namespace.XML_NAMESPACE; // xml prefix
Namespace noNS = Namespace.NO_NAMESPACE; // no namespace
// Namespace properties
String prefix = prefixedNS.getPrefix(); // "app"
String uri = prefixedNS.getURI(); // "http://example.com/app"
// Use with elements
Element root = DocumentHelper.createElement(QName.get("root", defaultNS));
root.addNamespace("app", "http://example.com/app");
Element child = root.addElement(QName.get("child", prefixedNS));
// Namespace equality
Namespace ns1 = Namespace.get("app", "http://example.com/app");
Namespace ns2 = Namespace.get("app", "http://example.com/app");
boolean equal = ns1.equals(ns2); // true - namespaces are cached
// Common namespace operations
Element element = root.element(QName.get("child", prefixedNS));
Namespace childNS = element.getNamespace();
List<Namespace> declared = root.declaredNamespaces();DOM4J provides several interfaces for text-based content in XML documents.
import org.dom4j.CharacterData;
public interface CharacterData extends Node {
void appendText(String text);
}import org.dom4j.Text;
// Text nodes represent XML text content
Text textNode = DocumentHelper.createText("Hello World");
element.add(textNode);
String content = textNode.getText();
textNode.setText("Modified content");import org.dom4j.CDATA;
// CDATA sections preserve whitespace and special characters
CDATA cdata = DocumentHelper.createCDATA("<script>alert('test');</script>");
element.add(cdata);
String content = cdata.getText(); // Original content preservedimport org.dom4j.Comment;
// XML comments
Comment comment = DocumentHelper.createComment("This is a comment");
element.add(comment);
String commentText = comment.getText();
comment.setText("Updated comment");import org.dom4j.ProcessingInstruction;
public interface ProcessingInstruction extends Node {
String getTarget();
void setTarget(String target);
String getText();
String getValue(String name);
Map<String, String> getValues();
void setValue(String name, String value);
void setValues(Map<String, String> data);
boolean removeValue(String name);
}// Create processing instructions
ProcessingInstruction xmlStylesheet = DocumentHelper.createProcessingInstruction(
"xml-stylesheet", "type=\"text/xsl\" href=\"style.xsl\"");
ProcessingInstruction appSpecific = DocumentHelper.createProcessingInstruction(
"myapp", Map.of("version", "1.0", "mode", "debug"));
// Access PI properties
String target = xmlStylesheet.getTarget(); // "xml-stylesheet"
String text = xmlStylesheet.getText(); // "type=\"text/xsl\" href=\"style.xsl\""
// Work with PI values
appSpecific.setValue("mode", "production");
String mode = appSpecific.getValue("mode"); // "production"
Map<String, String> allValues = appSpecific.getValues();import org.dom4j.Entity;
// Entity references
Entity entity = DocumentHelper.createEntity("copyright", "© 2023");
element.add(entity);
String name = entity.getName(); // "copyright"
String text = entity.getText(); // "© 2023"The core DOM4J API provides a comprehensive and flexible foundation for XML document manipulation. The interfaces are designed for extensibility while the default implementations provide efficient and robust behavior for most use cases. The namespace-aware design and XPath integration make DOM4J particularly suitable for complex XML processing tasks.
Install with Tessl CLI
npx tessl i tessl/maven-org-dom4j--dom4j