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.
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.
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?
ResponderEliminarde dónde sacas a en a.getNombre()??
ResponderEliminarSi te fijas el primer coche lo instacio asi:
EliminarCoche a = new Coche("seat 600", "rojo", 750);
por eso luego accedo a ese objeto referenciado con "a"
a.getNombre();
como puedo leer los nodos de una factura electronica?
ResponderEliminarhey como se cierra el archivo xml en el codigo, para poder abirlo mientras se esta ejecutando el programa
ResponderEliminarHola 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:
ResponderEliminarPaco
Pepe
Gracias de antemano