W3docs

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.

ModeloEstiloMemoriaIdeal para
DOMCarga el árbol completo en memoriaAltaAcceso aleatorio, edición, documentos pequeños/medianos
SAXEmpuja eventos al escanear (callbacks)BajaDocumentos grandes, streaming de solo lectura
StAXExtrae eventos bajo demanda (cursor)BajaDocumentos 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.

Advertencia

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.

java— editable, runs on the server

Conclusiones del ejemplo:

  • El análisis DOM no necesita ninguna dependencia externa — DocumentBuilderFactory y org.w3c.dom se incluyen con el JDK, por eso el programa imprime resultados sin nada en el classpath.
  • El nombre del elemento raíz impreso como catalog confirma que hay exactamente una raíz que envuelve todo el documento.
  • getElementsByTagName("book") devolvió un NodeList de longitud 2, por lo que se indexa como una lista y se convierte cada elemento a Element.
  • Los atributos (id) se leen con getAttribute, mientras que el contenido de texto (title, price) se lee con getTextContent — 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.50 es 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.

AspectoXMLJSON
SintaxisEtiquetas verbosas, apertura y cierreLlaves y corchetes compactos
AtributosSí (id="1")No — todo es un par clave/valor
ComentariosCompatible (<!-- ... -->)No compatible
Esquema/validaciónMaduro (XSD, DTD)JSON Schema, menos extendido
Soporte en JDKIntegrado (javax.xml.*)Ninguno nativo — requiere biblioteca
Uso típico hoyConfiguración, documentos, SOAP, sistemas legadosAPIs 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

Práctica

Práctica
¿Qué modelo de análisis XML carga el documento completo en memoria como un árbol navegable?
¿Qué modelo de análisis XML carga el documento completo en memoria como un árbol navegable?
Was this page helpful?