DOM
DOM (Document Object Model) es una interfaz de programación que permite analizar y manipular dinámicamente el contenido, estilo y estructura de un documento, originaria del W3C.

Todas las estructuras de datos del documento XML se transforman en algún tipo de nodo, organizados jerárquicamente en forma de árbol con nodos padre, hijo y finales (hojas).
JAXP
Para trabajar con XML desde Java se usa JAXP (Java API for XML Processing), que ofrece una manera transparente de utilizar diferentes parsers (como Xerces, Xalan, XT…).

Las clases principales se encuentran en el paquete javax.xml.parsers:
DocumentBuilderFactoryDocumentBuilder
Y las interfaces DOM en el paquete org.w3c.dom.

Fichero XML de ejemplo
<?xml version="1.0" encoding="UTF-8"?>
<Libros
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:noNamespaceSchemaLocation='LibrosEsquema.xsd'>
<Libro publicado_en="1840">
<Titulo>El Capote</Titulo>
<Autor>Nikolai Gogol</Autor>
</Libro>
<Libro publicado_en="2008">
<Titulo>El Sanador de Caballos</Titulo>
<Autor>Gonzalo Giner</Autor>
</Libro>
<Libro publicado_en="1981">
<Titulo>El Nombre de la Rosa</Titulo>
<Autor>Umberto Eco</Autor>
</Libro>
</Libros>
Clase GestionarDOM
Abrir un XML con DOM
public int abrir_XML_DOM(File fichero){
doc = null;
try{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.parse(fichero);
return 0;
}
catch(Exception e){
e.printStackTrace();
return -1;
}
}
Recorrer el árbol DOM
Importante: Para obtener el contenido de texto de un nodo hay que acceder al nodo hijo de tipo
TEXT_NODE, no al nodo elemento directamente.
public String recorrerDOMyMostrar(Document doc){
String datos_nodo[] = null;
String salida = "";
Node node;
Node raiz = doc.getFirstChild();
NodeList nodeList = raiz.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++){
node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE){
datos_nodo = procesarLibro(node);
salida = salida + "\n " + "Publicado en: " + datos_nodo[0];
salida = salida + "\n " + "El autor es: " + datos_nodo[2];
salida = salida + "\n " + "El título es: " + datos_nodo[1];
salida = salida + "\n --------------------";
}
}
return salida;
}
Procesar un nodo libro
protected String[] procesarLibro(Node n){
String datos[] = new String[3];
Node ntemp = null;
int contador = 1;
datos[0] = n.getAttributes().item(0).getNodeValue();
NodeList nodos = n.getChildNodes();
for (int i = 0; i <nodos.getLength(); i++){
ntemp = nodos.item(i);
if(ntemp.getNodeType() == Node.ELEMENT_NODE){
datos[contador] = ntemp.getChildNodes().item(0).getNodeValue();
contador++;
}
}
return datos;
}
Añadir un nodo al DOM
public int annadirDOM(Document doc, String titulo, String autor, String anno){
try{
Node ntitulo = doc.createElement("Titulo");
Node ntitulo_text = doc.createTextNode(titulo);
ntitulo.appendChild(ntitulo_text);
Node nautor = doc.createElement("Autor");
Node nautor_text = doc.createTextNode(autor);
nautor.appendChild(nautor_text);
Node nlibro = doc.createElement("Libro");
((Element)nlibro).setAttribute("publicado_en", anno);
nlibro.appendChild(ntitulo);
nlibro.appendChild(nautor);
Node raiz = doc.getChildNodes().item(0);
raiz.appendChild(nlibro);
return 0;
}
catch(Exception e){
e.printStackTrace();
return -1;
}
}
Guardar el DOM como fichero (con XMLSerializer)
public int guardarDOMcomoFILE(){
try{
File archivo_xml = new File("salida.xml");
OutputFormat format = new OutputFormat(doc);
format.setIndenting(true);
XMLSerializer serializer = new XMLSerializer(
new FileOutputStream(archivo_xml), format);
serializer.serialize(doc);
return 0;
}
catch(Exception e){
return -1;
}
}
Crear un XML desde cero (Método 1: XMLSerializer)
package GestionDOM;
public class PruebaGestionarDOM{
public static void main(String[] args){
GestionarDOM ObjetoDOM = new GestionarDOM();
ObjetoDOM.doc = null;
try{
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DOMImplementation implementation =
builder.getDOMImplementation();
ObjetoDOM.doc = implementation.createDocument(
null, "Libros", null);
ObjetoDOM.doc.setXMLVersion("1.0");
ObjetoDOM.annadirDOM(
ObjetoDOM.doc, "Desarrollo de Interfaces", "Pablo Martinez", "2010");
ObjetoDOM.annadirDOM(
ObjetoDOM.doc, "Acceso a datos", "Alberto Carrera", "2011");
ObjetoDOM.annadirDOM(
ObjetoDOM.doc, "Formación y orientación laboral",
"Belén Carrera", "2012");
ObjetoDOM.guardarDOMcomoFILE("D:\\profesores.XML");
}
catch(Exception e){
e.printStackTrace();
}
}
}
Crear un XML desde cero (Método 2: Transformer)
package GestionDOM;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.DOMSource;
public class PruebaGestionarDOM_1{
public static void main(String[] args){
GestionarDOM ObjetoDOM = new GestionarDOM();
ObjetoDOM.doc = null;
try{
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DOMImplementation implementation =
builder.getDOMImplementation();
ObjetoDOM.doc = implementation.createDocument(
null, "Libros", null);
ObjetoDOM.doc.setXMLVersion("1.0");
ObjetoDOM.annadirDOM(
ObjetoDOM.doc, "Desarrollo de Interfaces", "Pablo Martinez", "2010");
ObjetoDOM.annadirDOM(
ObjetoDOM.doc, "Acceso a datos", "Alberto Carrera", "2011");
ObjetoDOM.annadirDOM(
ObjetoDOM.doc, "Formación y orientación laboral",
"Belén Carrera", "2012");
Source source = new DOMSource(ObjetoDOM.doc);
Result result = new StreamResult(
new java.io.File("D:\\profesores.XML"));
Transformer transformer =
TransformerFactory.newInstance().newTransformer();
transformer.transform(source, result);
}
catch(Exception e){
e.printStackTrace();
}
}
}
El método Transformer es el estándar JAXP y no depende de librerías externas como Xerces, por lo que es preferible cuando se quiere portabilidad.