Java – Crear Archivo XML

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.

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 &amp; 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 &amp; 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.

Un XML sin sangrar es igual de válido y ocupa menos. La sangría es para que lo lea una persona: si el archivo lo va a consumir otro programa, puedes ahorrártela.

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 documentoDocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()
Un elementodoc.createElement("nombre") y padre.appendChild(hijo)
Un atributoelemento.setAttribute("clave", "valor")
El texto de dentroelemento.setTextContent("…")
GuardarloTransformer + StreamResult
Que se lea bienINDENT 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.

Deja un comentario