CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-dom4j--dom4j

Flexible XML framework for Java providing comprehensive XML processing capabilities

Pending
Overview
Eval results
Files

document-creation.mddocs/

DOM4J Document Creation and Parsing

This section covers creating XML documents, parsing XML from various sources, and using the factory classes that manage DOM4J object creation. DOM4J provides flexible approaches for both programmatic document creation and parsing XML from files, streams, and other sources.

DocumentHelper - Static Utility Class

DocumentHelper provides convenient static methods for creating DOM4J objects and performing common operations.

Package and Import

import org.dom4j.DocumentHelper;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Attribute;
import org.dom4j.DocumentException;

Document Creation

public final class DocumentHelper {
    // Document creation
    public static Document createDocument();
    public static Document createDocument(Element rootElement);
    
    // Parse text as XML
    public static Document parseText(String text) throws DocumentException;
}

Element and Attribute Creation

public final class DocumentHelper {
    // Element creation
    public static Element createElement(QName qname);
    public static Element createElement(String name);
    
    // Attribute creation
    public static Attribute createAttribute(Element owner, QName qname, String value);
    public static Attribute createAttribute(Element owner, String name, String value);
}

Node Creation Methods

public final class DocumentHelper {
    // Text content nodes
    public static CDATA createCDATA(String text);
    public static Comment createComment(String text);
    public static Text createText(String text);
    public static Entity createEntity(String name, String text);
    
    // Processing instructions
    public static ProcessingInstruction createProcessingInstruction(String target, String data);
    public static ProcessingInstruction createProcessingInstruction(String target, Map<String, String> data);
    
    // Namespace and QName
    public static Namespace createNamespace(String prefix, String uri);
    public static QName createQName(String localName, Namespace namespace);
    public static QName createQName(String localName);
}

XPath and Pattern Methods

public final class DocumentHelper {
    // XPath creation
    public static XPath createXPath(String xpathExpression) throws InvalidXPathException;
    public static XPath createXPath(String xpathExpression, VariableContext context) throws InvalidXPathException;
    
    // Pattern and filter creation
    public static NodeFilter createXPathFilter(String xpathFilterExpression);
    public static Pattern createPattern(String xpathPattern);
    
    // XPath operations on node collections
    public static List<Node> selectNodes(String xpathFilterExpression, List<Node> nodes);
    public static List<Node> selectNodes(String xpathFilterExpression, Node node);
    public static void sort(List<Node> list, String xpathExpression);
    public static void sort(List<Node> list, String expression, boolean distinct);
}

Utility Methods

public final class DocumentHelper {
    // Path-based element creation
    public static Element makeElement(Branch source, String path);
}

Using DocumentHelper

// Create empty document
Document document = DocumentHelper.createDocument();

// Create document with root element
Element root = DocumentHelper.createElement("catalog");
Document catalog = DocumentHelper.createDocument(root);

// Parse XML text
String xmlText = "<book><title>XML Guide</title></book>";
Document parsed = DocumentHelper.parseText(xmlText);

// Create various node types
Element product = DocumentHelper.createElement("product");
Attribute id = DocumentHelper.createAttribute(product, "id", "P123");
Comment comment = DocumentHelper.createComment("Product catalog");
CDATA cdata = DocumentHelper.createCDATA("<script>alert('test');</script>");
Text text = DocumentHelper.createText("Product description");

// Create namespaced elements
Namespace ns = DocumentHelper.createNamespace("catalog", "http://example.com/catalog");
QName productQName = DocumentHelper.createQName("product", ns);
Element nsProduct = DocumentHelper.createElement(productQName);

// XPath creation and usage
XPath xpath = DocumentHelper.createXPath("//product[@id]");
List<Node> products = xpath.selectNodes(document);

NodeFilter filter = DocumentHelper.createXPathFilter("self::product");
List<Node> filtered = document.selectNodes("//node()").stream()
    .filter(filter::matches)
    .collect(Collectors.toList());

// Path-based element creation
Element catalog = DocumentHelper.createElement("catalog");
Element book = DocumentHelper.makeElement(catalog, "books/book");
// Creates: catalog/books/book if they don't exist

DocumentFactory - Configurable Object Creation

DocumentFactory provides a configurable factory for creating all DOM4J objects with support for customization and singleton access.

Package and Import

import org.dom4j.DocumentFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.QName;

Singleton Access

public class DocumentFactory {
    // Singleton instance
    public static synchronized DocumentFactory getInstance();
}

Document Creation

public class DocumentFactory {
    // Document creation methods
    public Document createDocument();
    public Document createDocument(String encoding);
    public Document createDocument(Element rootElement);
    
    // Document type creation
    public DocumentType createDocType(String name, String publicId, String systemId);
}

Element Creation

public class DocumentFactory {
    // Element creation
    public Element createElement(QName qname);
    public Element createElement(String name);
    public Element createElement(String qualifiedName, String namespaceURI);
}

Attribute Creation

public class DocumentFactory {
    // Attribute creation
    public Attribute createAttribute(Element owner, QName qname, String value);
    public Attribute createAttribute(Element owner, String name, String value);
}

Content Node Creation

public class DocumentFactory {
    // Text-based nodes
    public CDATA createCDATA(String text);
    public Comment createComment(String text);
    public Text createText(String text);
    public Entity createEntity(String name, String text);
    
    // Processing instructions
    public ProcessingInstruction createProcessingInstruction(String target, String data);
    public ProcessingInstruction createProcessingInstruction(String target, Map<String, String> data);
}

QName and Namespace Creation

public class DocumentFactory {
    // Namespace creation
    public Namespace createNamespace(String prefix, String uri);
    
    // QName creation
    public QName createQName(String localName, Namespace namespace);
    public QName createQName(String localName);
    public QName createQName(String name, String prefix, String uri);
    public QName createQName(String qualifiedName, String uri);
}

XPath Creation

public class DocumentFactory {
    // XPath and pattern creation
    public XPath createXPath(String xpathExpression) throws InvalidXPathException;
    public XPath createXPath(String xpathExpression, VariableContext variableContext);
    public NodeFilter createXPathFilter(String xpathFilterExpression, VariableContext variableContext);
    public NodeFilter createXPathFilter(String xpathFilterExpression);
    public Pattern createPattern(String xpathPattern);
}

Configuration Methods

public class DocumentFactory {
    // QName management
    public List<QName> getQNames();
    
    // XPath namespace configuration
    public Map<String, String> getXPathNamespaceURIs();
    public void setXPathNamespaceURIs(Map<String, String> namespaceURIs);
}

Using DocumentFactory

// Get singleton instance
DocumentFactory factory = DocumentFactory.getInstance();

// Create document with encoding
Document document = factory.createDocument("UTF-8");

// Create elements
Element root = factory.createElement("catalog");
document.setRootElement(root);

Element product = factory.createElement("product");
root.add(product);

// Create namespaced elements
Element nsElement = factory.createElement("item", "http://example.com/catalog");

// Create attributes
Attribute id = factory.createAttribute(product, "id", "P123");
product.add(id);

// Create QNames and namespaces
Namespace catalogNS = factory.createNamespace("cat", "http://example.com/catalog");
QName productQName = factory.createQName("product", catalogNS);
Element nsProduct = factory.createElement(productQName);

// Create content nodes
Comment comment = factory.createComment("Generated catalog");
Text description = factory.createText("Product description");
CDATA script = factory.createCDATA("<script>processProduct();</script>");

document.add(comment);
product.add(description);

// Configure XPath namespaces
Map<String, String> namespaces = Map.of(
    "cat", "http://example.com/catalog",
    "prod", "http://example.com/product"
);
factory.setXPathNamespaceURIs(namespaces);

// Create XPath with configured namespaces
XPath xpath = factory.createXPath("//cat:product[@prod:id]");

Custom DocumentFactory

// Create custom factory for specialized behavior
public class CustomDocumentFactory extends DocumentFactory {
    @Override
    public Element createElement(QName qname) {
        // Return custom element implementation
        return new MyCustomElement(qname);
    }
    
    @Override
    public Attribute createAttribute(Element owner, QName qname, String value) {
        // Return custom attribute implementation
        return new MyCustomAttribute(qname, value);
    }
}

// Use custom factory
DocumentFactory customFactory = new CustomDocumentFactory();
Document document = customFactory.createDocument();
Element element = customFactory.createElement("custom");

XML Parsing with SAXReader

SAXReader creates DOM4J documents from XML sources using SAX parsing. It provides configurable parsing with support for validation, entity resolution, and custom error handling.

Package and Import

import org.dom4j.io.SAXReader;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.xml.sax.XMLReader;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;

SAXReader Construction

public class SAXReader {
    // Constructors
    public SAXReader();
    public SAXReader(boolean validating);
    public SAXReader(DocumentFactory factory);
    public SAXReader(XMLReader xmlReader);
    public SAXReader(String xmlReaderClassName) throws SAXException;
}

Reading Methods

public class SAXReader {
    // Read from various sources
    public Document read(File file) throws DocumentException;
    public Document read(InputSource in) throws DocumentException;
    public Document read(InputStream in) throws DocumentException;
    public Document read(Reader reader) throws DocumentException;
    public Document read(String systemId) throws DocumentException;
    public Document read(URL url) throws DocumentException;
}

Configuration Methods

public class SAXReader {
    // XMLReader configuration
    public void setXMLReader(XMLReader reader);
    public XMLReader getXMLReader() throws SAXException;
    public void setXMLReaderClassName(String className) throws SAXException;
    
    // Validation
    public boolean isValidating();
    public void setValidating(boolean validation);
    
    // Factory configuration
    public DocumentFactory getDocumentFactory();
    public void setDocumentFactory(DocumentFactory documentFactory);
    
    // Error handling
    public ErrorHandler getErrorHandler();
    public void setErrorHandler(ErrorHandler errorHandler);
    
    // Entity resolution
    public EntityResolver getEntityResolver();
    public void setEntityResolver(EntityResolver entityResolver);
}

Using SAXReader

// Basic parsing
SAXReader reader = new SAXReader();

// Parse from file
Document document = reader.read(new File("catalog.xml"));

// Parse from URL
Document webDoc = reader.read(new URL("http://example.com/data.xml"));

// Parse from string
String xmlContent = "<book><title>Guide</title></book>";
Document stringDoc = reader.read(new StringReader(xmlContent));

// Parse from input stream
try (InputStream is = new FileInputStream("data.xml")) {
    Document streamDoc = reader.read(is);
}

// Validating parser
SAXReader validatingReader = new SAXReader(true);
try {
    Document validDoc = validatingReader.read("valid.xml");
} catch (DocumentException e) {
    System.err.println("Validation error: " + e.getMessage());
}

// Custom error handling
reader.setErrorHandler(new ErrorHandler() {
    @Override
    public void warning(SAXParseException e) {
        System.out.println("Warning: " + e.getMessage());
    }
    
    @Override
    public void error(SAXParseException e) throws SAXException {
        System.err.println("Error: " + e.getMessage());
        throw e;
    }
    
    @Override
    public void fatalError(SAXParseException e) throws SAXException {
        System.err.println("Fatal: " + e.getMessage());
        throw e;
    }
});

// Custom entity resolver
reader.setEntityResolver(new EntityResolver() {
    @Override
    public InputSource resolveEntity(String publicId, String systemId) {
        if (systemId.endsWith("custom.dtd")) {
            return new InputSource(new StringReader("<!-- Custom DTD -->"));
        }
        return null; // Use default resolution
    }
});

// Custom document factory
DocumentFactory customFactory = new MyDocumentFactory();
reader.setDocumentFactory(customFactory);

// Parse with custom factory
Document customDoc = reader.read("data.xml");

Advanced Parsing Configuration

// Configure specific XMLReader
XMLReader xmlReader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
xmlReader.setFeature("http://xml.org/sax/features/validation", true);
xmlReader.setFeature("http://apache.org/xml/features/validation/schema", true);

SAXReader reader = new SAXReader(xmlReader);

// Set schema validation
xmlReader.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation",
    "http://example.com/schema http://example.com/schema.xsd");

// Parse with schema validation
try {
    Document document = reader.read("instance.xml");
    System.out.println("Document is valid");
} catch (DocumentException e) {
    System.err.println("Validation failed: " + e.getMessage());
}

Document Building Patterns

Programmatic Document Construction

// Create complete document structure
Document catalog = DocumentHelper.createDocument();

// Add XML declaration and encoding
catalog.setXMLEncoding("UTF-8");

// Add processing instruction
catalog.addProcessingInstruction("xml-stylesheet", 
    "type=\"text/xsl\" href=\"catalog.xsl\"");

// Create root element with namespace
Namespace catalogNS = Namespace.get("cat", "http://example.com/catalog");
Element root = catalog.addElement(QName.get("catalog", catalogNS));

// Add schema location
root.addNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
root.addAttribute(QName.get("schemaLocation", 
    Namespace.get("xsi", "http://www.w3.org/2001/XMLSchema-instance")),
    "http://example.com/catalog catalog.xsd");

// Build content using fluent interface
Element books = root.addElement("books");
Element book1 = books.addElement("book")
    .addAttribute("isbn", "123-456-789")
    .addAttribute("available", "true");

book1.addElement("title").addText("DOM4J Guide");
book1.addElement("author").addText("John Smith");
book1.addElement("price").addText("29.99");

// Add CDATA section for description
book1.addElement("description").add(
    DocumentHelper.createCDATA("<p>Complete guide to <b>DOM4J</b> XML processing.</p>"));

// Add comment
books.addComment("More books will be added");

Template-based Document Creation

// Create document template
public class CatalogBuilder {
    private final DocumentFactory factory;
    private final Namespace catalogNS;
    
    public CatalogBuilder() {
        this.factory = DocumentFactory.getInstance();
        this.catalogNS = factory.createNamespace("cat", "http://example.com/catalog");
    }
    
    public Document createCatalog(String title, String version) {
        Document document = factory.createDocument("UTF-8");
        
        Element root = document.addElement(factory.createQName("catalog", catalogNS));
        root.addAttribute("version", version);
        root.addAttribute("title", title);
        root.addAttribute("generated", Instant.now().toString());
        
        return document;
    }
    
    public Element addBook(Element catalog, String isbn, String title, String author) {
        Element books = catalog.element("books");
        if (books == null) {
            books = catalog.addElement("books");
        }
        
        return books.addElement("book")
            .addAttribute("isbn", isbn)
            .addElement("title").addText(title).getParent()
            .addElement("author").addText(author).getParent();
    }
}

// Use template
CatalogBuilder builder = new CatalogBuilder();
Document catalog = builder.createCatalog("Technical Books", "1.0");
Element book = builder.addBook(catalog.getRootElement(), 
    "123-456-789", "XML Processing", "Jane Doe");

Streaming Document Creation

// For large documents, build incrementally
public class StreamingCatalogBuilder {
    private final Document document;
    private final Element booksElement;
    
    public StreamingCatalogBuilder() {
        this.document = DocumentHelper.createDocument();
        Element root = document.addElement("catalog");
        this.booksElement = root.addElement("books");
    }
    
    public void addBook(Map<String, String> bookData) {
        Element book = booksElement.addElement("book");
        
        bookData.forEach((key, value) -> {
            if ("isbn".equals(key)) {
                book.addAttribute("isbn", value);
            } else {
                book.addElement(key).addText(value);
            }
        });
    }
    
    public Document getDocument() {
        return document;
    }
    
    public void writeToFile(String filename) throws IOException {
        try (FileWriter writer = new FileWriter(filename)) {
            XMLWriter xmlWriter = new XMLWriter(writer, OutputFormat.createPrettyPrint());
            xmlWriter.write(document);
        }
    }
}

// Stream processing
StreamingCatalogBuilder builder = new StreamingCatalogBuilder();

// Process data source (e.g., database results)
while (resultSet.next()) {
    Map<String, String> bookData = Map.of(
        "isbn", resultSet.getString("isbn"),
        "title", resultSet.getString("title"),
        "author", resultSet.getString("author"),
        "price", resultSet.getString("price")
    );
    builder.addBook(bookData);
}

builder.writeToFile("catalog.xml");

Exception Handling in Document Creation

DocumentException Handling

import org.dom4j.DocumentException;

try {
    // Parsing operations that may fail
    SAXReader reader = new SAXReader();
    Document document = reader.read("malformed.xml");
    
} catch (DocumentException e) {
    // Get detailed error information
    String message = e.getMessage();
    Throwable cause = e.getCause();
    
    // Handle specific error types
    if (cause instanceof SAXParseException) {
        SAXParseException saxError = (SAXParseException) cause;
        int line = saxError.getLineNumber();
        int column = saxError.getColumnNumber();
        System.err.printf("Parse error at line %d, column %d: %s%n", 
            line, column, saxError.getMessage());
    } else {
        System.err.println("Document processing error: " + message);
    }
}

Validation Error Handling

// Custom error handler for validation
class ValidationErrorHandler implements ErrorHandler {
    private final List<String> errors = new ArrayList<>();
    private final List<String> warnings = new ArrayList<>();
    
    @Override
    public void warning(SAXParseException e) {
        warnings.add(formatError("WARNING", e));
    }
    
    @Override
    public void error(SAXParseException e) {
        errors.add(formatError("ERROR", e));
    }
    
    @Override
    public void fatalError(SAXParseException e) throws SAXException {
        String message = formatError("FATAL", e);
        errors.add(message);
        throw new SAXException(message);
    }
    
    private String formatError(String level, SAXParseException e) {
        return String.format("%s [%d:%d]: %s", 
            level, e.getLineNumber(), e.getColumnNumber(), e.getMessage());
    }
    
    public List<String> getErrors() { return new ArrayList<>(errors); }
    public List<String> getWarnings() { return new ArrayList<>(warnings); }
    public boolean hasErrors() { return !errors.isEmpty(); }
}

// Use validation handler
SAXReader reader = new SAXReader(true);
ValidationErrorHandler errorHandler = new ValidationErrorHandler();
reader.setErrorHandler(errorHandler);

try {
    Document document = reader.read("document.xml");
    
    if (errorHandler.hasErrors()) {
        System.err.println("Validation errors:");
        errorHandler.getErrors().forEach(System.err::println);
    }
    
    if (!errorHandler.getWarnings().isEmpty()) {
        System.out.println("Validation warnings:");
        errorHandler.getWarnings().forEach(System.out::println);
    }
    
} catch (DocumentException e) {
    System.err.println("Parse failed: " + e.getMessage());
}

DOM4J's document creation and parsing capabilities provide both simplicity for basic operations and flexibility for advanced XML processing requirements. The combination of static helper methods, configurable factories, and robust parsing support makes it suitable for a wide range of XML processing scenarios from simple document creation to complex enterprise XML processing pipelines.

Install with Tessl CLI

npx tessl i tessl/maven-org-dom4j--dom4j

docs

advanced-features.md

core-api.md

document-creation.md

index.md

io-operations.md

xpath.md

tile.json