Para escribir XML, el JDK trae todo lo necesario desde hace veinte años y no hace falta ninguna dependencia. Son dos piezas: DocumentBuilder construye el árbol en memoria y Transformer lo vuelca a un archivo.
También te puede interesar
El programa entero
import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
public class CrearXml {
public static void main(String[] args) throws Exception {
var fabrica = DocumentBuilderFactory.newInstance();
Document doc = fabrica.newDocumentBuilder().newDocument();
Element raiz = doc.createElement("catalogo");
doc.appendChild(raiz);
Element libro = doc.createElement("libro");
libro.setAttribute("id", "1");
raiz.appendChild(libro);
Element titulo = doc.createElement("titulo");
titulo.setTextContent("El Quijote");
libro.appendChild(titulo);
Element autor = doc.createElement("autor");
autor.setTextContent("Cervantes & Saavedra");
libro.appendChild(autor);
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
t.transform(new DOMSource(doc), new StreamResult(new File("catalogo.xml")));
}
}catalogo.xml<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<catalogo>
<libro id="1">
<titulo>El Quijote</titulo>
<autor>Cervantes & Saavedra</autor>
</libro>
</catalogo>Lo que conviene mirar de cerca
El ampersand se ha escapado solo. En el código se escribió Cervantes & Saavedra y en el archivo aparece Cervantes & Saavedra, que es lo correcto. Esa es la razón de fondo para no generar XML concatenando cadenas a mano: el &, el < y las comillas de un atributo producen un archivo inválido en cuanto un dato trae uno.
La sangría necesita las dos propiedades. Con INDENT a yes pero sin indent-amount, muchas implementaciones sangran con cero espacios y el archivo sale en una sola línea. La clave larga entre llaves no es un error: es una propiedad específica del transformador de Xalan, y así es como se pasa.
Escribir a otro sitio
// a una cadena, para devolverla por HTTP var escritor = new StringWriter(); t.transform(new DOMSource(doc), new StreamResult(escritor)); String xml = escritor.toString(); // a la salida estándar, para depurar t.transform(new DOMSource(doc), new StreamResult(System.out));
StreamResult acepta un archivo, un flujo o un escritor, así que el mismo código vale para guardar, para enviar y para mirar.
| Para… | Usa |
|---|---|
| Crear el documento | DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() |
| Un elemento | doc.createElement("nombre") y padre.appendChild(hijo) |
| Un atributo | elemento.setAttribute("clave", "valor") |
| El texto de dentro | elemento.setTextContent("…") |
| Guardarlo | Transformer + StreamResult |
| Que se lea bien | INDENT e indent-amount |
Más información en inglés: Create an XML file in Java.
Todo el código se compiló y se ejecutó con Java 25 LTS en un contenedor limpio antes de publicar esta página; las salidas están copiadas de esa ejecución.