🌲 dom4j Cheatsheet Completo 🌲

dom4j es una biblioteca de código abierto para Java que proporciona una forma amigable y flexible de trabajar con XML, utilizando los principios del DOM (Document Object Model) y SAX (Simple API for XML). Es conocida por su rendimiento, su API concisa y su integración con XPath y JAXB.


1. 🌟 Conceptos Clave


2. 🛠️ Configuración Inicial (Maven)

Añade la dependencia en tu pom.xml:

<dependencies>
    <dependency>
        <groupId>org.dom4j</groupId>
        <artifactId>dom4j</artifactId>
        <version>2.1.4</version> &lt;!-- Usar la versión más reciente y estable -->
    </dependency>
    &lt;!-- Opcional: Para XPath, si no está en tu JDK o si necesitas una implementación específica -->
    &lt;!-- dom4j usa la implementación XPath de JAXP por defecto, que suele estar en el JDK.
         Si tienes problemas con JAXP o quieres algo diferente, puedes añadir:
    <dependency>
        <groupId>jaxen</groupId>
        <artifactId>jaxen</artifactId>
        <version>1.2.0</version>
    </dependency>
    -->
</dependencies>

3. 📄 Creación de Documentos XML

3.1. Crear un Documento Simple

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import java.io.FileWriter;
import java.io.IOException;

public class CreateXml {
    public static void main(String[] args) throws IOException {
        // 1. Crear un nuevo documento
        Document document = DocumentHelper.createDocument();

        // 2. Añadir el elemento raíz
        Element root = document.addElement("library");

        // 3. Añadir elementos hijos y atributos
        Element book1 = root.addElement("book")
                            .addAttribute("id", "1")
                            .addAttribute("category", "fiction");
        book1.addElement("title").setText("El Señor de los Anillos");
        book1.addElement("author").setText("J.R.R. Tolkien");
        book1.addElement("year").setText("1954");

        Element book2 = root.addElement("book")
                            .addAttribute("id", "2")
                            .addAttribute("category", "science");
        book2.addElement("title").setText("Cosmos");
        book2.addElement("author").setText("Carl Sagan");
        book2.addElement("year").setText("1980");

        // 4. Guardar el documento en un archivo
        try (FileWriter out = new FileWriter("library.xml")) {
            document.write(out);
        }
        System.out.println("Archivo 'library.xml' creado exitosamente.");
        System.out.println("XML generado:\n" + document.asXML()); // Imprime a consola
    }
}

4. 📁 Lectura y Parseo de Documentos XML

4.1. Cargar un Documento desde un Archivo

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import java.io.File;

public class ReadXmlFromFile {
    public static void main(String[] args) throws DocumentException {
        File xmlFile = new File("library.xml"); // Asume que 'library.xml' existe
        if (!xmlFile.exists()) {
            System.out.println("Archivo 'library.xml' no encontrado. Por favor, créalo primero.");
            return;
        }

        // 1. Crear un lector SAX (recomendado para cargar)
        SAXReader reader = new SAXReader();
        // Opcional: Validar XML durante la lectura
        // reader.setValidation(true); // Requiere un DTD o Schema
        // reader.setFeature("http://apache.org/xml/features/validation/schema", true); // Para XML Schema

        // 2. Leer el documento
        Document document = reader.read(xmlFile);

        // 3. Acceder al elemento raíz
        System.out.println("Elemento raíz: " + document.getRootElement().getName());
        System.out.println("Número de libros: " + document.getRootElement().elements("book").size());
    }
}

4.2. Cargar un Documento desde un String

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

public class ReadXmlFromString {
    public static void main(String[] args) throws DocumentException {
        String xmlString = "<person><name>Alice</name><age>30</age></person>";

        Document document = DocumentHelper.parseText(xmlString);
        Element root = document.getRootElement();
        System.out.println("Nombre: " + root.elementText("name"));
        System.out.println("Edad: " + root.elementText("age"));
    }
}

5. 🔍 Navegación y Consulta (DOM-like)

5.1. Acceder a Elementos y Atributos

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Attribute;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.Iterator;
import java.util.List;

public class NavigateXml {
    public static void main(String[] args) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("library.xml"));
        Element root = document.getRootElement(); // <library>

        // Acceder a elementos hijos por nombre
        Element firstBook = root.element("book"); // Primer elemento <book>
        System.out.println("Primer libro: " + firstBook.elementText("title"));

        // Acceder a atributos
        Attribute idAttr = firstBook.attribute("id");
        System.out.println("ID del primer libro: " + idAttr.getValue());
        // O directamente: firstBook.attributeValue("id")

        // Iterar sobre todos los elementos hijos con un nombre específico
        List<Element> books = root.elements("book"); // Devuelve una lista de todos los <book>
        System.out.println("\nTodos los libros:");
        for (Element book : books) {
            System.out.println("- " + book.elementText("title") + " (" + book.attributeValue("category") + ")");
        }

        // Iterar sobre todos los elementos hijos (sin importar el nombre)
        System.out.println("\nIterando todos los hijos de la raíz:");
        for (Iterator<Element> it = root.elementIterator(); it.hasNext(); ) {
            Element element = it.next();
            System.out.println("Elemento: " + element.getName());
        }

        // Iterar sobre todos los atributos de un elemento
        System.out.println("\nAtributos del primer libro:");
        for (Iterator<Attribute> it = firstBook.attributeIterator(); it.hasNext(); ) {
            Attribute attr = it.next();
            System.out.println("  " + attr.getName() + " = " + attr.getValue());
        }
    }
}

6. 🌐 Consultas con XPath

dom4j tiene un excelente soporte para XPath.

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node; // Importa Node para XPath
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;

public class XPathQuery {
    public static void main(String[] args) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("library.xml"));

        // Seleccionar todos los títulos de libros
        List<Node> titles = document.selectNodes("//book/title"); // // para cualquier nivel, / para hijo directo
        System.out.println("Títulos de libros:");
        for (Node node : titles) {
            System.out.println("- " + node.getText()); // Obtiene el texto del nodo
        }

        // Seleccionar libros de categoría "fiction"
        List<Node> fictionBooks = document.selectNodes("//book[@category='fiction']"); // @ para atributo
        System.out.println("\nLibros de ficción:");
        for (Node node : fictionBooks) {
            Element book = (Element) node; // Castear a Element para acceder a sus métodos
            System.out.println("- " + book.elementText("title"));
        }

        // Seleccionar el autor del libro con ID "1"
        Node authorNode = document.selectSingleNode("//book[@id='1']/author"); // selectSingleNode para un único resultado
        if (authorNode != null) {
            System.out.println("\nAutor del libro con ID 1: " + authorNode.getText());
        }

        // Seleccionar el precio de un libro (si existiera)
        // Node priceNode = document.selectSingleNode("//book[@id='1']/price");
        // if (priceNode != null) {
        //     System.out.println("Precio: " + priceNode.getText());
        // }
    }
}

7. ✍️ Modificación de Documentos XML

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

public class ModifyXml {
    public static void main(String[] args) throws DocumentException, IOException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("library.xml"));
        Element root = document.getRootElement();

        // 1. Modificar un elemento existente
        Element book1 = root.element("book"); // Obtener el primer libro
        Element title1 = book1.element("title");
        title1.setText("El Señor de los Anillos (Edición Extendida)"); // Modificar texto del título

        // 2. Modificar un atributo existente
        book1.attribute("category").setValue("fantasy"); // Cambiar la categoría

        // 3. Añadir un nuevo elemento a un existente
        book1.addElement("publisher").setText("Allen & Unwin");

        // 4. Añadir un nuevo atributo a un existente
        book1.addAttribute("language", "en");

        // 5. Eliminar un elemento
        List<Element> books = root.elements("book");
        if (books.size() > 1) {
            root.remove(books.get(1)); // Eliminar el segundo libro (<book id="2">Cosmos</book>)
            System.out.println("Segundo libro eliminado.");
        }

        // 6. Eliminar un atributo
        if (book1.attribute("id") != null) {
            book1.remove(book1.attribute("id"));
            System.out.println("Atributo 'id' del primer libro eliminado.");
        }

        // 7. Guardar los cambios en un nuevo archivo o sobrescribir
        OutputFormat format = OutputFormat.createPrettyPrint(); // Formato bonito para salida
        try (FileWriter out = new FileWriter("modified_library.xml");
             XMLWriter writer = new XMLWriter(out, format)) {
            writer.write(document);
        }
        System.out.println("Archivo 'modified_library.xml' creado con cambios.");
    }
}

8. 💡 Buenas Prácticas y Consejos


Este cheatsheet te proporciona una referencia completa de dom4j, cubriendo sus conceptos esenciales, cómo crear, leer y modificar documentos XML, el uso de XPath y las mejores prácticas para un manejo eficiente de XML en Java.