Escritura XML sencilla con Java (DOM) xml-apis

Una manera sencilla de escribir archivos sencillos de XML con java es con la libreria xml-apis DOM.
Es una libreria que utiliza estructura de nodos para crear/leer un XML.

Para poder tener esta libreria en nuestro proyecto y usarla, es necesario añadir esta dependencia maven:

      <dependency>
        <groupId>xml-apis</groupId>
        <artifactId>xml-apis</artifactId>
        <version>2.0.2</version>
    </dependency>    


O importar el  xml-apis_2.0.1.jar a nuestro classpath.

Vamos alla, para empezar a usarlo necesitamos seguir los siguientes pasos:
1. Instanciar un objeto de la clase java que queremos representar en el xml. (Este ejemplo mapea clases sencillas, para cosas mas complejas recomiendo usar JAXB o realizar tareas con el API java.reflection).

        //objeto a parsear a XML
        Coche a = new Coche("seat 600", "rojo", 750);

2. Crear una factoria de DocumentBuilder al que le pediremos un objeto Document con el que podamos trabajar. Este objeto Document ya es capaz de crear y manejar estructuras con nodos.

        //Creo una factoria a la que pedir objetos builder
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       
        //Obtengo una instancia
        DocumentBuilder db = dbf.newDocumentBuilder();

        //Creo el arbol vacio de nodos, pero ya esta la estructura
        Document dom = db.newDocument();

3.Ahora con el objeto Document, es solamente especificar que elementos queremos y su contenido. Mediante los metodos que facilita Document, podemos crear elementos, insertarlos dentro de otros elementos, rellenar los elementos con texto , etc.... Vamos a crear algo sencillo:

        //Creo el elemento principal <Coche>
        Element elemento_raiz = dom.createElement("Coche");
        dom.appendChild(elemento_raiz);

esto nos crearía en memoria una estructura parecida a esto:
<?xml version="1.0" encoding="UTF-8"?>
<Coche>
</Coche>


Vemos que tenemos un elemento Coche que es la raiz, ahora vamos a añadirle mas elementos a ese nodo "elemento_raiz".

        //NOMBRE <Nombre> Creo el nodo <Nombre> y le meto contenido Texto
        Element nombre_elemento = dom.createElement("Nombre");//creo el nodo de elemento
        Text nombre_contenido = dom.createTextNode(a.getNombre());//creo el nodo de texto
        nombre_elemento.appendChild(nombre_contenido);//meto el nodo de texto dentro del nodo elemento
        elemento_raiz.appendChild(nombre_elemento); //lo meto en el bloque principal

Al elemento raiz le hemos añadido un nuevo elemento <Nombre> que tiene contenido de texto dentro .Si ahora imprimieramos el documento tendria esta estructura:

<?xml version="1.0" encoding="UTF-8"?>
<Coche>
    <Nombre>seat 600</Nombre>
</Coche>


Ahora solo faltaria añadir el resto de elementos que queramos y en el orden que queramos.
Este es un ejemplo final de un ejecutable java que lee un objeto coche y saca su representacion a un archivo XML mediante un Stream.





import java.io.File;
import java.io.FileOutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

//Clase modelo que representa un coche
class Coche{
    private String nombre;
    private String color;
    private int precio;
    public String getNombre() {
        return nombre;
    }
    public String getColor() {
        return color;
    }
    public int getPrecio() {
        return precio;
    }

    public Coche (String nombre, String color, int precio){
        this.nombre= nombre;
        this.color= color;
        this.precio= precio;
    }
}


public class DOMXMLWritter {
    /**
     * @param args
     */
    public static void main(String[] args) {
        //objeto a parsear a XML
        Coche a = new Coche("seat 600", "rojo", 750);
        //Creo una factoria a la que pedir objetos builder
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
        //Obtengo una instancia
        DocumentBuilder db = dbf.newDocumentBuilder();

        //Creo el arbol vacio de nodos, pero ya esta la estructura
        Document dom = db.newDocument();
       
        //Creo el elemento principal <Coche>
        Element elemento_raiz = dom.createElement("Coche");
        dom.appendChild(elemento_raiz);
       
        //NOMBRE <Nombre> Creo el nodo <Nombre> y le meto contenido Texto
        Element nombre_elemento = dom.createElement("Nombre");//creo el nodo de elemento
        Text nombre_contenido = dom.createTextNode(a.getNombre());//creo el nodo de texto
        nombre_elemento.appendChild(nombre_contenido);//meto el nodo de texto dentro del nodo elemento
        elemento_raiz.appendChild(nombre_elemento); //lo meto en el bloque principal
       
        //COLOR <Color> Creo el nodo <Color> y le meto contenido Texto
        Element color_elemento = dom.createElement("Color");//creo el nodo de elemento
        Text color_contenido = dom.createTextNode(a.getColor());//creo el nodo de texto
        color_elemento.appendChild(color_contenido);//meto el nodo de texto dentro del nodo elemento
        elemento_raiz.appendChild(color_elemento); //lo meto en el bloque principal

        //PRECIO <Precio> Creo el nodo <Precio> y le meto contenido Texto
        Element precio_elemento = dom.createElement("Precio");//creo el nodo de elemento
        Text precio_contenido = dom.createTextNode(String.valueOf(a.getPrecio()));//creo el nodo de texto
        precio_elemento.appendChild(precio_contenido);//meto el nodo de texto dentro del nodo elemento
        elemento_raiz.appendChild(precio_elemento); //lo meto en el bloque principal
       
               
        //Voy a sacarlo a un file (por ejemplo)
        File archivo_coche_xml = new File("C:"+File.separator+"XMLExamples"+File.separator+"Coche.xml");
       
        //Especifico formato
        OutputFormat format = new OutputFormat(dom);
        format.setIndenting(true);
       
        //Escribo en el archivo a traves del Stream
        XMLSerializer serializer = new XMLSerializer(new FileOutputStream(archivo_coche_xml), format);

        serializer.serialize(dom);
       
       
        }catch(Exception e) {
            //dump it
            System.out.println("Ha habido un error " + e.getMessage());
            System.exit(1);
        }
       
    }

}




Este ejemplo es muy sencillo y estamos creando los nodos a mano, pero podriamos usar el API Reflection de Java para parsear a XML cualquier clase sin necesidad de conocer sus metodos y propiedades.
Aunque para esta tarea recomiendo mirar la libreria JAXB que esta bastante bien.





Comentarios

  1. Buen dia, el elemento nombre tiene la informacion seat 600 se puede guardar con ese nombre el archivo que lo fuera a tomar dependiendo de lo que le salga en ese elemento? soy nuevo en esto de la programacion y quiero hacer esto y no se como hacerlo?

    ResponderEliminar
  2. de dónde sacas a en a.getNombre()??

    ResponderEliminar
    Respuestas
    1. Si te fijas el primer coche lo instacio asi:

      Coche a = new Coche("seat 600", "rojo", 750);

      por eso luego accedo a ese objeto referenciado con "a"

      a.getNombre();

      Eliminar
  3. como puedo leer los nodos de una factura electronica?

    ResponderEliminar
  4. hey como se cierra el archivo xml en el codigo, para poder abirlo mientras se esta ejecutando el programa

    ResponderEliminar
  5. Hola Daniel, tengo una duda. Como sería para añadir varios nodos igual dentro de una misma etiqueta, es que estoy intentandolo pero es como si me lo machacase. Me refiero a esto:

    Paco
    Pepe


    Gracias de antemano

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Subir campos Blob a BBDD (Oracle) con Java

Reiniciar usuario de SVN Subversion

Cucumber y Java - definiendo test de una manera amigable