Ficheros XML

De ChuWiki
Saltar a: navegación, buscar

Dos formas de leer un fichero XML

Para leer un fichero XML existen dos formas básicas (dos APIs): SAX y DOM.

Por medio de SAX, una clase standard de java se va encargando de leer el fichero y nos va avisando según va leyendo tags de XML. Nosotros debemos hacer unas clases con unos métodos concretos que son los que van recibiendo estos tags.

Por medio de DOM, una clase standar de java se encarga de leer todo el fichero XML de golpe. Luego nos lo da en forma de Document para que nosotros lo vayamos analizando y haciendo lo que debamos con él.


Ventajas e inconvenientes de SAX y DOM

SAX es más complejo de programar, pero no carga todo el fichero en memoria como DOM.

DOM permite además escribir en el fichero XML, mientras que SAX no permite escribir.



Lectura de un fichero XML con DOM

El siguiente código lee un fichero XML y lo carga como un Document

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ( );
Document documento = null;

try
{
   DocumentBuilder builder = factory.newDocumentBuilder();
   documento = builder.parse( new File(nombreFicheroXML) );
}
catch (Exception spe)
{
   // Algún tipo de error: fichero no accesible, formato de XML incorrecto, etc.
}

Una vez ejecuta esto, si todo ha ido bien, en documento tendremos los datos del fichero XML. Para analizar este documento, debemos hacer cosas como esta:

// Nos devuelve el nodo raíz del documento XML.
Node nodoRaiz = documento.getFirstChild();

Si nuestro fichero XML fuera

<nodo_raiz>
   <nodo_hijo nombre_atributo="valor">
   </nodo_hijo>
</nodo_raiz>

En nodoRaiz tendríamos algo que representa a "nodo_raiz" del fichero XML.

Dado un nodo (raíz o no), podemos obtener sus nodos hijo así

// Devuelve nodos hijos de un nodo dado
NodeList listaNodosHijos = nodo.getChildNodes();
for (int i=0; i<listaNodosHijo.getLength(); i++)
   Node unNodoHijo = listaNodosHijo.item(i);

En el ejemplo anterior, nuestra lista de nodos hijos de "nodo_raiz" sería un único hijo "nodo_hijo".

Para obtener los atributos de un nodo, usamos los siguientes métodos

// Obtener los atributos de un nodo
NamedNodeMap atributos = unNodo.getAttributes(  );
Node unAtributo = atributos.getNamedItem( "nombre_atributo" );
String valorAtributo = unAtributo.getNodeValue();

En nuestro ejemplo XML, los atributos de "nodo_hijo" sería un sólo atributo de nombre "nombre_atibuto", cuyo valor es "valor".

Escritura de un fichero XML con DOM

Supongamos que ya tenemos creado nuestro Document, bien porque hemos leído un fichero XML y lo hemos modificado, bien porque lo hemos creado con código, a base de añadir los nodos y atributos uno a uno. Vamos ahora a escribir este Document en un fichero XML.

En primer lugar, la clase javax.xml.transform.TransformerFactory nos permite conseguir instancias de Transformer. Esta clase, a su vez, nos permite transformar una fuente XML (en concreto nuestro Document) en otra cosa (en nuestro caso, un fichero XML). Como fuente XML usaremos la clase DOMSource, que se puede instanciar pasándole nuestro Document. Como destino de la transformación, usaremos un StreamResult, al que pasaremos un File. El código de todo esto puede ser el siguiente:

// Document de XML
Document documento = ....;

// Obtención del TransfomerFactory y del Transformer a partir de él.
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();

// Creación de la fuente XML a partir del documento.
DOMSource source = new DOMSource(documento);

// Creación del resultado, que será un fichero.
StreamResult result = new StreamResult(new File("otro.xml"));

// Se realiza la transformación, de Document a Fichero.
transformer.transform(source, result);

En el siguiente ejemplo completo vemos todo junto. Leemos un fichero XML usando DOM para obtener el Document y lo escribimos en otro fichero XML, usando también DOM. Es similar a un copy de ficheros, pero leyéndolo y escibiéndolo como XML.

package com.chuidiang.ejemplos.xml;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

public class EjemploLecturaEscrituraXML {

	/**
	 * Ejemplo de lectura y escritura de un fichero xml
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			// Lectura de fichero_origen.xml
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document documento = builder.parse(new File("fichero_origen.xml"));
			
			// Ahora documento es el XML leido en memoria.

			// Escritura de fichero_destino.xml
			TransformerFactory transformerFactory = TransformerFactory
					.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(documento);
			StreamResult result = new StreamResult(new File("fichero_destino.xml"));
			transformer.transform(source, result);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}