Introducción a XML en Java
Introducción al procesamiento XML en Java con DOM, SAX, StAX y JAXB, con ejemplos y comparación con JSON.
XML (Extensible Markup Language) es un formato de texto para representar datos estructurados y jerárquicos mediante etiquetas anidadas. Mucho antes de que JSON dominara las APIs web, XML era el estándar para archivos de configuración, formatos de documentos e intercambio de mensajes — y sigue estando en todas partes, desde archivos pom.xml de Maven hasta servicios SOAP y documentos de Office.
Java ofrece soporte XML completo y nativo en el JDK: no se necesita ninguna biblioteca externa para leer o escribir XML. Los paquetes javax.xml.parsers y org.w3c.dom, junto con org.xml.sax y javax.xml.stream, ofrecen tres modelos de análisis distintos. Este capítulo explica qué es XML, qué modelo de análisis conviene usar en cada caso y cómo se compara XML con JSON — para que el resto de esta parte (DOM, SAX y JAXB) se construya sobre una base sólida.
Esta página cubre:
- Cómo es un documento XML y los términos necesarios (elemento, atributo, raíz, bien formado).
- Los tres modelos de análisis del JDK — DOM, SAX y StAX — y cuándo usar cada uno.
- Un ejemplo ejecutable de DOM usando únicamente clases del JDK.
- Las diferencias entre XML y JSON, para poder elegir entre ellos.
Cómo es XML
Un documento XML es un árbol de elementos. Cada elemento tiene un nombre, atributos opcionales y contenido de texto o elementos hijos anidados. Siempre hay exactamente un elemento raíz que envuelve todo.
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book id="1" lang="en">
<title>Effective Java</title>
<price>45.00</price>
</book>
</catalog>Aquí <catalog> es la raíz, <book> es un elemento hijo con dos atributos (id y lang), y <title> y <price> contienen texto. La declaración XML en la primera línea indica la versión y la codificación de caracteres. Un XML bien formado requiere que cada etiqueta de apertura esté cerrada y correctamente anidada.
Los tres modelos de análisis
El JDK ofrece tres formas de leer XML, cada una con un equilibrio diferente entre comodidad y memoria. Elegir el adecuado es la decisión más importante que tomarás al trabajar con XML.
| Modelo | Estilo | Memoria | Ideal para |
|---|---|---|---|
| DOM | Carga el árbol completo en memoria | Alta | Acceso aleatorio, edición, documentos pequeños/medianos |
| SAX | Empuja eventos al escanear (callbacks) | Baja | Documentos grandes, streaming de solo lectura |
| StAX | Extrae eventos bajo demanda (cursor) | Baja | Documentos grandes, con flujo de control más sencillo |
DOM construye un árbol completo en memoria que se puede navegar y modificar libremente. SAX dispara callbacks (startElement, characters, endElement) mientras lee, sin retener nunca el documento completo. StAX también es streaming, pero permite que tu código extraiga el siguiente evento cuando esté listo, lo que suele ser más fácil de seguir que los callbacks de SAX.
DOM: el árbol en memoria
DOM es el modelo más cómodo cuando los documentos son lo suficientemente pequeños como para caber en memoria. Se analiza una vez y luego se recorre o consulta el árbol tantas veces como se desee.
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc = factory.newDocumentBuilder().parse("catalog.xml");
NodeList books = doc.getElementsByTagName("book");
System.out.println("Books: " + books.getLength());getElementsByTagName devuelve un NodeList en vivo; se indexa y se convierten los nodos a Element para leer atributos y texto de los hijos. El capítulo dedicado al analizador DOM XML de Java explica en detalle cómo navegar, modificar y escribir el árbol.
By default the JDK parser resolves external entities, which exposes you to XXE (XML External Entity) attacks when parsing untrusted input. For production code that reads XML from outside your control, disable DTDs with factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); before creating the builder.
SAX y StAX: streaming
Cuando un documento es demasiado grande para cargarlo en memoria, se procesa en streaming. SAX empuja eventos a un handler que se suministra:
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.Attributes;
DefaultHandler handler = new DefaultHandler() {
public void startElement(String uri, String local, String name, Attributes a) {
System.out.println("Start: " + name);
}
};
SAXParserFactory.newInstance().newSAXParser()
.parse("catalog.xml", handler);StAX proporciona un cursor que se avanza manualmente, lo que muchos encuentran más claro:
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamConstants;
import java.io.FileReader;
XMLStreamReader r = XMLInputFactory.newInstance()
.createXMLStreamReader(new FileReader("catalog.xml"));
while (r.hasNext()) {
if (r.next() == XMLStreamConstants.START_ELEMENT) {
System.out.println("Start: " + r.getLocalName());
}
}Consulta el capítulo del analizador SAX XML de Java para una guía completa de los manejadores de eventos. Si prefieres omitir el análisis manual de nodos y mapear XML directamente a objetos Java, JAXB vincula elementos a clases anotadas por ti.
Un ejemplo autocontenido
El ejemplo ejecutable a continuación usa únicamente clases del JDK — no se necesita Jackson ni JAXB. Analiza un catálogo XML desde una cadena en memoria con DOM, recorre los elementos <book>, lee atributos y texto de los hijos, y suma los precios.
Conclusiones del ejemplo:
- El análisis DOM no necesita ninguna dependencia externa —
DocumentBuilderFactoryyorg.w3c.domse incluyen con el JDK, por eso el programa imprime resultados sin nada en el classpath. - El nombre del elemento raíz impreso como
catalogconfirma que hay exactamente una raíz que envuelve todo el documento. getElementsByTagName("book")devolvió unNodeListde longitud 2, por lo que se indexa como una lista y se convierte cada elemento aElement.- Los atributos (
id) se leen congetAttribute, mientras que el contenido de texto (title,price) se lee congetTextContent— son tipos de datos distintos en el mismo elemento. - Como el árbol completo está en memoria, sumar los precios de todos los libros para obtener
$83.50es simplemente un bucle con acceso aleatorio — la comodidad que hace que DOM valga su coste en memoria.
¿XML o JSON?
XML y JSON resuelven el mismo problema — intercambiar datos estructurados — pero con compromisos diferentes.
| Aspecto | XML | JSON |
|---|---|---|
| Sintaxis | Etiquetas verbosas, apertura y cierre | Llaves y corchetes compactos |
| Atributos | Sí (id="1") | No — todo es un par clave/valor |
| Comentarios | Compatible (<!-- ... -->) | No compatible |
| Esquema/validación | Maduro (XSD, DTD) | JSON Schema, menos extendido |
| Soporte en JDK | Integrado (javax.xml.*) | Ninguno nativo — requiere biblioteca |
| Uso típico hoy | Configuración, documentos, SOAP, sistemas legados | APIs web/REST, servicios modernos |
Usa XML cuando debas consumir un formato XML existente (un servicio SOAP, un pom.xml, un documento de Office) o cuando necesites atributos, comentarios o validación estricta de esquema. Usa JSON para nuevas APIs web, donde su menor tamaño y el soporte nativo del navegador son ventajas.
Próximos pasos
- Analizador DOM XML de Java — leer, modificar y escribir el árbol.
- Analizador SAX XML de Java — procesar documentos grandes con manejadores de eventos.
- JAXB — mapear XML desde y hacia objetos Java anotados.
- Introducción a JSON en Java — la alternativa moderna para datos web.