tratamiento de xml en java

27
JAVA Tratamiento de XML en Java (lectura y escritura) Publicado el 8 junio, 2011 por meta En esta ocasion os traigo una entrada en la que vamos a aprender a procesar ficheros en formato XML, las API más importantes que se usan en Java y las diferencias básicas entre ellas. Estas dos API van a ser DOM y SAX. Recordemos, previo a las explicaciones, que los ficheros XML se usan básicamente para tratar datos, ya sea para estructurarlos, para enviar y recibir datos o como base de datos. La principal idea de los ficheros XML es que son portables, e independientes del lenguaje de programación que usemos para procesarlos, además de ser simples de editar a mano y fáciles de comprender. Existen dos formas de procesar los ficheros XML en Java, básicamente. Por una parte tenemos el modelo DOM (Document Object Model) y por otra parte tenemos el SAX (Simple Api for XML). DOM A la hora de procesar un documento XML con DOM, la representación que tenemos va a ser la de un árbol jerárquico en memoria. Esto implica varias cosas: Podemos leer cualquier parte del árbol (todo es un nodo), de forma que podemos procesar de arriba a abajo pero también podemos volver atrás. Podemos modificar cualquier nodo del árbol. Al estar cargado en memoria, podemos tener una falta de ésta. Con ficheros XML pequeños no tendremos problemas, pero si tuvieramos un árbol muy muy grande entonces tendríamos una falta de heap space. Comentadas las características de DOM, pasemos a explicar cómo vamos a procesar documentos con DOM. Nuestro árbol en memoria va a ser un Document . Para crear un objeto de esta clase nos valdremos de las factorías de Document, de la siguiente manera: 1 // Meta @ vidasconcurrentes 2 try { 3 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 4 DocumentBuilder db = dbf.newDocumentBuilder(); 5 Document doc = db.newDocument(); 6 } catch (ParserConfigurationException e) { 7 e.printStackTrace(); 8} - 1 -

Upload: pcdproyecto

Post on 20-Oct-2015

37 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Tratamiento de XML en Java

JAVA

Tratamiento de XML en Java (lectura y escritura)Publicado el 8 junio, 2011 por meta

En esta ocasion os traigo una entrada en la que vamos a aprender a procesar ficheros en formato XML, las API más importantes que se usan en Java y las diferencias básicas entre ellas.Estas dos API van a ser DOM y SAX.

Recordemos, previo a las explicaciones, que los ficheros XML se usan básicamente para tratar datos, ya sea para estructurarlos, para enviar y recibir datos o como base de datos. La principal idea de los ficheros XML es que son portables, e independientes del lenguaje de programación que usemos para procesarlos, además de ser simples de editar a mano y fáciles de comprender.

Existen dos formas de procesar los ficheros XML en Java, básicamente. Por una parte tenemos el modelo DOM (Document Object Model) y por otra parte tenemos el SAX (Simple Api for XML).

DOM

A la hora de procesar un documento XML con DOM, la representación que tenemos va a ser la de un árbol jerárquico en memoria. Esto implica varias cosas:

• Podemos leer cualquier parte del árbol (todo es un nodo), de forma que podemos procesar de arriba a abajo pero también podemos volver atrás.

• Podemos modificar cualquier nodo del árbol. • Al estar cargado en memoria, podemos tener una falta de ésta. Con ficheros XML

pequeños no tendremos problemas, pero si tuvieramos un árbol muy muy grande entonces tendríamos una falta de heap space.

Comentadas las características de DOM, pasemos a explicar cómo vamos a procesar documentos con DOM. Nuestro árbol en memoria va a ser un Document. Para crear un objeto de esta clase nos valdremos de las factorías de Document, de la siguiente manera:

1 // Meta @ vidasconcurrentes

2 try {

3 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

4 DocumentBuilder db = dbf.newDocumentBuilder();5 Document doc = db.newDocument();

6 } catch (ParserConfigurationException e) {7 e.printStackTrace();8 }

- 1 -

Page 2: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

9 10 // forma compacta11 12 try {

13 Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();

14 } catch (ParserConfigurationException e) {15 e.printStackTrace();16 }

Ya tenemos un Document en memoria que representa nuestro árbol del que saldrá el fichero XML. Sin embargo este árbol no tiene ni siquiera un nodo raíz, así que el siguiente paso es crearlo:

1 Element root = doc.createElement("Raiz");

Damos por hecho que la variable doc ya existe del paso previo. El parámetro String que recibe la función createElement() es el texto de la etiqueta.Cada vez que queramos crear un nuevo nodo, deberemos llamar a esta función. En caso de querer añadir el texto correspondiente a un nodo, usaremos la función createTextElement(), que recibe un String que será el texto que contenga.

1 Element nodo = doc.createElement("NombreElemento");2 Text texto = doc.createTextNode("Texto del elemento");

Existe una cosa más en los ficheros XML, y son los atributos. Un nodo (una etiqueta), puede tener una serie de atributos a los cuales nosotros asignamos nombre y valor, o puede no tener ninguno. De esta forma podríamos agregar al nodo raíz el atributo autor con valor vidasConcurrentes, de la siguiente forma:

1 root.setAttribute("autor", "vidasConcurrentes");

En cualquiera de los casos, en DOM todo es un nodo, de modo que la forma de agregar nodos es la misma, independientemente del tipo de nodo que sea. Sabiendo esto, solamente nos faltaría agregar cada nodo a su nodo padre:

1 nodo.appendChild(texto);2 root.appendChild(nodo);3 doc.appendChild(root);

Con esto hemos conseguido tener nuestro Documentcreado y cargado en memoria. Sin embargo esto no tiene formato y necesitaríamos dárselo para posteriormente escribirlo en algún lugar. En este caso vamos a escribirlo en un fichero de texto:

1 // Meta @ vidasconcurrentes

2 try {3 // volcamos el XML al fichero

4 TransformerFactory transFact = TransformerFactory.newInstance();

- 2 -

Page 3: Tratamiento de XML en Java

JAVA

5 6 // añadimos sangrado y la cabecera de XML

7 transFact.setAttribute("indent-number", new Integer(3));8 Transformer trans = transFact.newTransformer();9 trans.setOutputProperty(OutputKeys.INDENT, "yes");

10 trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");

11 12 // hacemos la transformacion

13 StringWriter sw = new StringWriter();14 StreamResult sr = new StreamResult(sw);15 DOMSource domSource = new DOMSource(dom);16 trans.transform(domSource, sr);17 } catch(Exception ex) {18 ex.printStackTrace();19 }

Esto nos deja en la variable swla representación XML de este documento, con su sangrado correspondiente y listo para ser tratado. Ahora podríamos escribirlo por pantalla, por fichero, mandarlo por un Socket… en este caso agregamos un poco de código para escribirlo en un fichero:

1 // Meta @ vidasconcurrentes

2 try {3 // creamos fichero para escribir en modo texto

4 PrintWriter writer = new PrintWriter(new FileWriter("test.xml"));

5 6 // escribimos todo el arbol en el fichero7 writer.println(sw.toString());8 9 // cerramos el fichero10 writer.close();

11 } catch (IOException e) {12 e.printStackTrace();13 }

Teniendo esto habremos conseguido un fichero de texto XML a partir de un árbol cuya representación será de la siguiente forma:

1 <Raiz autor="vidasConcurrentes">2 <NombreElemento>Texto del elemento</NombreElemento>3 </Raiz>

Por otra parte, podemos querer leer un fichero XML y procesarlo de alguna manera. Para

- 3 -

Page 4: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

conseguir esto, primero necesitamos crear un Document en memoria a partir de un fichero XML bien formado:

1 // Meta @ vidasconcurrentes

2 try {

3 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

4 DocumentBuilder db = dbf.newDocumentBuilder();

5 Document doc = db.parse(new File("test.xml"));6 doc.getDocumentElement().normalize();

7 } catch (ParserConfigurationException e) {8 e.printStackTrace();

9 } catch (SAXException e) {10 e.printStackTrace();

11 } catch (IOException e) {12 e.printStackTrace();13 }

Es importante darse cuenta de que podemos crear el Document a partir de una sola línea de código, con todos los constructores anidados.Si tenemos un fichero XML mal formado recibiremos una excepción. La función normalize() elimina nodos de texto vacíos y combina los adyacentes (en caso de que los hubiera).Para poder acceder al nodo raíz del documento, vamos a utilizar la función getDocumentElement() del Document. Y a partir de aquí podemos empezar a recorrer el árbol.Cuando tenemos un nodo, por ejemplo el nodo raíz, podemos obtener todos los nodos que cuelgan de él con la función getChildNodes(). Sin embargo, esta función puede dar lugar a errores, y lo vamos a ver en un ejemplo.

Digamos que tenemos el fichero generado en la parte anterior, y lo leemos con el código que acabamos de poner. Si pidiéramos los hijos de nuestro nodo raíz, esperaríamos obtener sólo un nodo, que en este caso será el nodo con nombre NombreElemento. Pero lo obtenido es diferente:

1System.out.println(doc.getDocumentElement().getChildNodes().getLength());

2 // output: 3

Veamos qué nodos son estos:

1 NodeList nodosRaiz = doc.getDocumentElement().getChildNodes();

2 for(int i = 0; i < nodosRaiz.getLength(); i++) {3 System.out.println(nodosRaiz.item(i).getNodeName());4 }5 6 // output: #text7 // NombreElemento

- 4 -

Page 5: Tratamiento de XML en Java

JAVA

8 // #text

Además, si miramos esos nodos de tipo #text veremos que no son nada. De modo que para evitarlos podríamos filtrarlos con un if(!nodosRaiz.item(i).getNodeName().equals(“#text”)…o también podríamos seleccionar los nodos que deseamos por el nombre, puesto que sabemos el nombre de los nodos de cada nivel:

1NodeList nodosRaiz = doc.getDocumentElement().getElementsByTagName("NombreElemento");

2 System.out.println(nodosRaiz.getLength());3 System.out.println(nodosRaiz.item(0).getNodeName());4 5 // output: 16 // NombreElemento

Es decir, la manera de ir leyendo los diferentes hijos de cada nodo es usando o bien getChildNodes() e ir filtrando por nombres (con un case por ejemplo), o bien usar varios getElementsByTagName()en caso de tener etiquetas de nombres diferentes en el mismo nivel.Recordemos que nuestro nodo raíz tenía un atributo. Supongamos que quisiéramos sacar el valor por alguna razón. El código sería el siguiente:

1System.out.println(doc.getDocumentElement().getAttribute("autor"));

2 3 // output: vidasConcurrentes

En caso de no ser el nodo raíz no se pondría doc.getDocumentElement() sino el Element correspondiente.

Con esto hemos cubierto el tema de tratamiento de XML con DOM en Java. Puedes ver un ejemplo completo en nuestro repositorio.

SAX

Al contrario que con DOM, al procesar en SAX no vamos a tener la representación completa del árbol en memoria, pues SAX funciona con eventos. Esto implica:

• Al no tener el árbol completo no puede volver atrás, pues va leyendo secuencialmente.

• La modificación de un nodo es mucho más compleja (y la inserción de nuevos nodos).

• Como no tiene el árbol en memoria es mucho más memory friendly, de modo que es la única opción viable para casos de ficheros muy grandes, pero demasiado complejo para ficheros pequeños.

• Al ser orientado a eventos, el procesado se vuelve bastante complejo.

De esta forma, no vamos a explicar cómo escribir o modificar ficheros con SAX debido a su complejidad y nuestra falta de espacio, sino cómo leerlos y procesarlos.

Vamos a partir de que tenemos ya el fichero XML anterior:

- 5 -

Page 6: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

1 <Raiz autor="vidasConcurrentes">2 <NombreElemento>Texto del elemento</NombreElemento>3 </Raiz>

Para poder procesar un fichero XML con SAX vamos a necesitar que nuestra clase lectora va a necesitar heredar de la clase DefaultHandler (recordemos que, como buena práctica de programación, los datos deben estar separados de la entrada/salida). Además vamos a necesitar un objeto de la clase XMLReader, el cual va a usar la propia clase como ContentHandler y ErrorHandler. El esqueleto de la clase entonces, sería algo así:

1 public class LectorXML_SAX extends DefaultHandler {2 3 private XMLReader reader;4 5 public LectorXML_SAX() {6 try {7 reader = XMLReaderFactory.createXMLReader();8 reader.setContentHandler(this);9 reader.setErrorHandler(this);

10 } catch (SAXException e) {11 e.printStackTrace();12 }13 }14 }

Hemos dicho que SAX funciona por eventos. Pero ¿qué eventos son esos? Pues bien, los eventos son los siguientes:

• startDocument(): llamado cuando empieza el documento. • endDocument(): llamado cuando acaba el documento. • startElement(): llamado cuando empieza un nodo (por ejemplo, al llegar al < en

<Raiz>). • characters(): llamado al acabar el evento startElement(). Sirve para leer el

contenido de una etiqueta (por ejemplo, el texto Texto del elemento de la etiqueta NombreElemento).

• endElement(): llamado al llegar al final de una etiqueta (por ejemplo, al llegar al </ en </NombreElemento>).

Ahora crearemos nuestra función para la lectura, de la siguiente manera:

1 public void leeXML(String path) {2 try {3 reader.parse(path);

4 } catch (IOException e) {5 e.printStackTrace();

- 6 -

Page 7: Tratamiento de XML en Java

JAVA

6 } catch (SAXException e) {7 e.printStackTrace();8 }9 }

Al ejecutar esto nos damos cuenta de que no hemos obtenido nada. Esto es así porque las funciones explicadas más arriba para los eventos están vacías y necesitamos redefinirlas. En nuestro caso vamos a volcar el contenido del fichero por pantalla, sin sangrado:

1 @Override

2 public void startElement(String uri, String localName, String name, Attributes atts) {

3 System.out.println("<" + localName + ">");4 }5 6 @Override

7 public void characters(char[] cadena, int inicio, int length) {

8 if(String.valueOf(cadena, inicio, length).trim().length() != 0)

9 System.out.println(String.valueOf(cadena, inicio, length));

10 } 11 12 @Override

13 public void endElement(String uri, String name, String qName) {14 System.out.println("");15 }

Si creasemos un objeto de esta clase e invocásemos a la función leerXML(), obtendríamos lo siguiente por la consola:

1 <Raiz><NombreElemento>Texto del elemento</NombreElemento></Raiz>

A partir de esto podríamos, en lugar de escribir por pantalla los valores, procesarlos y crear atributos de objetos de clases que hayamos definido nosotros. Un ejemplo de esto se puede encontrar aquí.

A lo largo de esta entrada, por tanto, hemos visto cómo crear ficheros XML con DOM y cómo recorrer el árbol que crea, y también hemos visto cómo leer ficheros XML con SAX.

Nuestra pequeña recomendación es que, si el fichero es pequeño o relativamente pequeño, la opción más cómoda es DOM. Si se necesita modificar el árbol jerárquico, la única opción no es DOM pero sí la más viable, ya que hacer esto con SAX es muy complejo. En caso de solo lectura y procesado, SAX es la opción más rápida y que menos memoria gasta, pero es mucho más compleja y es menos instintiva. Si el documento es demasiado extenso… entonces SAX es la única opción.

A partir de estos dos métodos surgieron diversas librerías como JDOM, que facilitan este procesado de datos.

- 7 -

Page 9: Tratamiento de XML en Java

JAVA

MainTest.java/* * Author: Meta | http://vidasconcurrentes.blogspot.com * Related to: http://vidasconcurrentes.blogspot.com/2011/06/tratamiento-de-xml-en-java-lectura-y.html */

package com.vidasconcurrentes.javaxml;

import java.util.ArrayList;

public class MainTest {

public static void main(String[] args) { int lectura_o_escritura = 0; // 0 == escritura, 1 == lectura switch(lectura_o_escritura) { case 0: // lista de pedidos ArrayList<Pedido> pedidos = new ArrayList<Pedido>(); // usuarios Usuario user1 = new Usuario("Neo", "Thomas", "Anderson"); Usuario user2 = new Usuario("Cifra", "Mr.", "Regan"); // productos Producto product1 = new Producto("Matrix 7.0"); Producto product2 = new Producto("Reinsercion 1.0"); Producto product3 = new Producto("Gravedad 2.0"); // creamos el primer pedido Pedido pedido1 = new Pedido(1, user1); pedido1.addProducto(product1); pedido1.addProducto(product3); // creamos el segundo pedido Pedido pedido2 = new Pedido(2, user2); pedido2.addProducto(product2); // añadimos los pedidos a la lista pedidos.add(pedido1); pedidos.add(pedido2); // creamos los procesadores en DOM y en SAX PedidosXML_DOM dom = new PedidosXML_DOM(); PedidosXML_SAX sax = new PedidosXML_SAX();

- 9 -

Page 10: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

// escritura con DOM dom.pedidosToXML(pedidos, "pedidos.xml"); break; case 1: // lectura de fichero, quitar comentario en el caso que se quiera probar ArrayList<Pedido> pedidosLeidos; // pedidosLeidos = dom.XMLtoPedidos("pedidos.xml"); // pedidosLeidos = sax.XMLtoPedidos("pedidos.xml"); break; default: System.out.println("lectura_o_escritura == 0 -> Escritura"); System.out.println("lectura_o_escritura == 1 -> Lectura"); break; } }}

- 10 -

Page 11: Tratamiento de XML en Java

JAVA

Pedido

/* * Author: Meta | http://vidasconcurrentes.blogspot.com * Related to: http://vidasconcurrentes.blogspot.com/2011/06/tratamiento-de-xml-en-java-lectura-y.html */

package com.vidasconcurrentes.javaxml;

import java.util.ArrayList;

public class Pedido {

private int numeroPedido; private Usuario cliente; private ArrayList<Producto> listaProductos; public Pedido(int numeroPedido, Usuario cliente) { this.numeroPedido = numeroPedido; this.cliente = cliente; this.listaProductos = new ArrayList<Producto>(); } public int getNumeroPedido() { return numeroPedido; }

public Usuario getCliente() { return cliente; }

public ArrayList<Producto> getListaProductos() { return listaProductos; }

public void addProducto(Producto producto) { this.listaProductos.add(producto); }}

- 11 -

Page 12: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

PedidosXML_DOM.java

/* * Author: Meta | http://vidasconcurrentes.blogspot.com * Related to: http://vidasconcurrentes.blogspot.com/2011/06/tratamiento-de-xml-en-java-lectura-y.html */

package com.vidasconcurrentes.javaxml;

import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;import java.io.StringWriter;import java.util.ArrayList;import java.util.Date;

import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import javax.xml.transform.OutputKeys;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;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.w3c.dom.Text;import org.xml.sax.SAXException;

public class PedidosXML_DOM {

private Document dom; public PedidosXML_DOM() { dom = null; } private void addCliente(Usuario cliente, Element nodoCliente) { Element nombre = dom.createElement("Nombre"); Text textoNombre = dom.createTextNode(cliente.getNombre());

- 12 -

Page 13: Tratamiento de XML en Java

JAVA

nombre.appendChild(textoNombre); Element apellido = dom.createElement("Apellido"); Text textoApellido = dom.createTextNode(cliente.getApellido()); apellido.appendChild(textoApellido); Element user = dom.createElement("User"); Text textoUser = dom.createTextNode(cliente.getUser()); user.appendChild(textoUser); nodoCliente.appendChild(nombre); nodoCliente.appendChild(apellido); nodoCliente.appendChild(user); } private void addProducto(Producto producto, Element nodoProducto) { Element nombre = dom.createElement("Nombre"); Text textoNombre = dom.createTextNode(producto.getNombre()); nombre.appendChild(textoNombre); Element fechaAlta = dom.createElement("FechaAlta"); Text textoFechaAlta = dom.createTextNode(String.valueOf(producto.getFechaAlta().getTime())); fechaAlta.appendChild(textoFechaAlta); nodoProducto.appendChild(nombre); nodoProducto.appendChild(fechaAlta); } private void addProductos(ArrayList<Producto> listaProductos, Element nodoListaProductos) { for(int i = 0; i < listaProductos.size(); i++) { Element producto = dom.createElement("Producto"); addProducto(listaProductos.get(i), producto); nodoListaProductos.appendChild(producto); } } private void addPedido(Pedido pedido) { // seleccionamos la raiz Element root = dom.getDocumentElement(); // creamos un nuevo elemento con el atributo del numero de producto Element unPedido = dom.createElement("Pedido"); unPedido.setAttribute("numeroPedido", String.valueOf(pedido.getNumeroPedido())); // creamos un nuevo elemento para el cliente

- 13 -

Page 14: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

Element cliente = dom.createElement("Cliente"); addCliente(pedido.getCliente(), cliente); // creamos un nuevo elemento para los productos de los que consta el pedido Element productos = dom.createElement("Productos"); addProductos(pedido.getListaProductos(), productos); // insertamos el cliente y los productos en el elemento del pedido unPedido.appendChild(cliente); unPedido.appendChild(productos); // insertamos el pedido en la raiz root.appendChild(unPedido); } /* * Escribe en el fichero la representacion del árbol XML */ private void write(StringWriter sw, String path) { try { // creamos fichero para escribir en modo texto PrintWriter writer = new PrintWriter(new FileWriter(path)); // escribimos todo el arbol en XML writer.println(sw.toString()); // cerramos el fichero writer.close(); } catch (IOException e) { e.printStackTrace(); } }

/* * Transforma el árbol, agregando la cabecera y añadiendo sangrados */ private void toFile(String ruta) { try { // volcamos el XML al fichero TransformerFactory transFact = TransformerFactory.newInstance(); // añadimos sangrado transFact.setAttribute("indent-number", new Integer(3)); Transformer trans = transFact.newTransformer();

- 14 -

Page 15: Tratamiento de XML en Java

JAVA

// incluimos la cabecera XML y el sangrado trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); trans.setOutputProperty(OutputKeys.INDENT, "yes"); // hacemos la transformacion StringWriter sw = new StringWriter(); StreamResult sr = new StreamResult(sw); DOMSource domSource = new DOMSource(dom); trans.transform(domSource, sr); // escribimos en el fichero write(sw, ruta); } catch(Exception ex) { ex.printStackTrace(); } } /* * Creamos un fichero XML a partir de una lista de pedidos */ public void pedidosToXML(ArrayList<Pedido> pedidos, String ruta) { // creamos un nuevo Document donde vamos a guardar toda la estructura try { dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Element root = dom.createElement("Pedidos"); dom.appendChild(root); } catch (ParserConfigurationException e) { e.printStackTrace(); } for(int i = 0; i < pedidos.size(); i++) addPedido(pedidos.get(i)); // volcamos por pantalla toFile(ruta); } // Lectura de XML con DOM private Usuario readUsuario(Node nodoUsuario) { Element elementoUsuario = (Element)nodoUsuario; String nombre = elementoUsuario.getElementsByTagName("Nombre").item(0).getTextContent(); String apellido = elementoUsuario.getElementsByTagName("Apellido").item(0).getTextContent(); String user = elementoUsuario.getElementsByTagName("User").item(0).getTextContent(); return new Usuario(nombre, apellido, user);

- 15 -

Page 16: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

} private Producto readProducto(Node nodoProducto) { Element elementoProducto = (Element)nodoProducto; String nombre = elementoProducto.getElementsByTagName("Nombre").item(0).getTextContent(); long fechaAlta = Long.valueOf(elementoProducto.getElementsByTagName("FechaAlta").item(0).getTextContent()); return new Producto(nombre, new Date(fechaAlta)); } private Pedido readPedido(Node nodoPedido) { Element elementoPedido = (Element)nodoPedido; int numeroPedido = Integer.valueOf(elementoPedido.getAttribute("numeroPedido")); Usuario user = readUsuario(elementoPedido.getElementsByTagName("Cliente").item(0)); Pedido pedido = new Pedido(numeroPedido, user); NodeList productos = elementoPedido.getElementsByTagName("Productos"); for(int i = 0; i < productos.getLength(); i++) { pedido.addProducto(readProducto((Element)productos.item(0))); } return pedido; } /* * Creamos una lista de pedidos procesando un fichero XML */ public ArrayList<Pedido> XMLtoPedidos(String ruta) { ArrayList<Pedido> pedidos = new ArrayList<Pedido>(); try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); dom = db.parse(new File(ruta)); dom.getDocumentElement().normalize(); // seleccionamos todos los pedidos y vamos leyendo NodeList listaPedidos = dom.getDocumentElement().getElementsByTagName("Pedido"); for(int i = 0; i < listaPedidos.getLength(); i++) { pedidos.add(readPedido(listaPedidos.item(i))); }

- 16 -

Page 17: Tratamiento de XML en Java

JAVA

} catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } return pedidos; }}

- 17 -

Page 18: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

PedidosXML_SAX.java

/* * Author: Meta | http://vidasconcurrentes.blogspot.com * Related to: http://vidasconcurrentes.blogspot.com/2011/06/tratamiento-de-xml-en-java-lectura-y.html */

package com.vidasconcurrentes.javaxml;

import java.io.IOException;import java.util.ArrayList;

import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.XMLReader;import org.xml.sax.helpers.DefaultHandler;import org.xml.sax.helpers.XMLReaderFactory;

public class PedidosXML_SAX extends DefaultHandler {

private XMLReader reader; public PedidosXML_SAX() { try { reader = XMLReaderFactory.createXMLReader(); reader.setContentHandler(this); reader.setErrorHandler(this); } catch (SAXException e) { e.printStackTrace(); } } public ArrayList<Pedido> XMLtoPedidos(String ruta) { ArrayList<Pedido> pedidos = new ArrayList<Pedido>(); try { reader.parse(ruta); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } return pedidos;

- 18 -

Page 19: Tratamiento de XML en Java

JAVA

} @Override public void startElement(String uri, String localName, String name, Attributes atts) { System.out.println("<" + localName + ">"); } @Override public void characters(char[] cadena, int inicio, int length) { if(String.valueOf(cadena, inicio, length).trim().length() != 0) System.out.println(String.valueOf(cadena, inicio, length)); } @Override public void endElement(String uri, String name, String qName) { System.out.println("</" + name +">"); }}

- 19 -

Page 20: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

Producto.java

/* * Author: Meta | http://vidasconcurrentes.blogspot.com * Related to: http://vidasconcurrentes.blogspot.com/2011/06/tratamiento-de-xml-en-java-lectura-y.html */

package com.vidasconcurrentes.javaxml;

import java.util.Date;

public class Producto {

private String nombre; private Date fechaAlta; private void init(String nombre, Date fechaAlta) { this.nombre = nombre; this.fechaAlta = fechaAlta; } public Producto(String nombre) { init(nombre, new Date()); } public Producto(String nombre, Date fechaAlta) { init(nombre, fechaAlta); }

public String getNombre() { return nombre; }

public Date getFechaAlta() { return fechaAlta; }}

- 20 -

Page 21: Tratamiento de XML en Java

JAVA

Usuario.java

/* * Author: Meta | http://vidasconcurrentes.blogspot.com * Related to: http://vidasconcurrentes.blogspot.com/2011/06/tratamiento-de-xml-en-java-lectura-y.html */

package com.vidasconcurrentes.javaxml;

public class Usuario {

private String user; private String nombre; private String apellido; public Usuario(String user, String nombre, String apellido) { this.user = user; this.nombre = nombre; this.apellido = apellido; }

public String getUser() { return user; }

public String getNombre() { return nombre; }

public String getApellido() { return apellido; }}

- 21 -

Page 22: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

pedidos.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?><Pedidos> <Pedido numeroPedido="1"> <Cliente> <Nombre>Thomas</Nombre> <Apellido>Anderson</Apellido> <User>Neo</User> </Cliente> <Productos> <Producto> <Nombre>Matrix 7.0</Nombre> <FechaAlta>1307542390468</FechaAlta> </Producto> <Producto> <Nombre>Gravedad 2.0</Nombre> <FechaAlta>1307542390468</FechaAlta> </Producto> </Productos> </Pedido> <Pedido numeroPedido="2"> <Cliente> <Nombre>Mr.</Nombre> <Apellido>Regan</Apellido> <User>Cifra</User> </Cliente> <Productos> <Producto> <Nombre>Reinsercion 1.0</Nombre> <FechaAlta>1307542390468</FechaAlta> </Producto> </Productos> </Pedido></Pedidos>

- 22 -

Page 23: Tratamiento de XML en Java

JAVA

test.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?><Raiz autor="vidasConcurrentes"> <NombreElemento>Texto del elemento</NombreElemento></Raiz>

- 23 -

Page 24: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

How to read XML file in Java – (SAX Parser)

Posted on December 7, 2008 , Last modified : August 4, 2011 By mkyong

SAX parser is work differently with DOM parser, it either load any XML document into memory nor create any object representation of the XML document. Instead, the SAX parser use callback function (org.xml.sax.helpers.DefaultHandler) to informs clients of the XML document structure.SAX Parser is faster and uses less memory than DOM parser.

See following SAX callback methods :

• startDocument() and endDocument() – Method called at the start and end of an XML document.

• startElement() and endElement() – Method called at the start and end of a document element.

• characters() – Method called with the text contents in between the start and end tags of an XML document element.

1. XML file

Create a simple XML file.<?xml version="1.0"?><company> <staff> <firstname>yong</firstname> <lastname>mook kim</lastname> <nickname>mkyong</nickname> <salary>100000</salary> </staff> <staff> <firstname>low</firstname> <lastname>yin fong</lastname> <nickname>fong fong</nickname> <salary>200000</salary> </staff></company>

2. Java file

Use SAX parser to parse the XML file.import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.xml.sax.Attributes;import org.xml.sax.SAXException;

- 24 -

Page 25: Tratamiento de XML en Java

JAVA

import org.xml.sax.helpers.DefaultHandler; public class ReadXMLFile { public static void main(String argv[]) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); DefaultHandler handler = new DefaultHandler() { boolean bfname = false; boolean blname = false; boolean bnname = false; boolean bsalary = false; public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException { System.out.println("Start Element :" + qName); if (qName.equalsIgnoreCase("FIRSTNAME")) { bfname = true; } if (qName.equalsIgnoreCase("LASTNAME")) { blname = true; } if (qName.equalsIgnoreCase("NICKNAME")) { bnname = true; } if (qName.equalsIgnoreCase("SALARY")) { bsalary = true; } } public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("End Element :" + qName); } public void characters(char ch[], int start, int length) throws SAXException { if (bfname) { System.out.println("First Name : " + new String(ch, start, length)); bfname = false; } if (blname) { System.out.println("Last Name : " + new String(ch,

- 25 -

Page 26: Tratamiento de XML en Java

Tratamiento de XML en Java (lectura y escritura)

start, length)); blname = false; } if (bnname) { System.out.println("Nick Name : " + new String(ch, start, length)); bnname = false; } if (bsalary) { System.out.println("Salary : " + new String(ch, start, length)); bsalary = false; } } }; saxParser.parse("c:\\file.xml", handler); } catch (Exception e) { e.printStackTrace(); } } }

ResultStart Element :companyStart Element :staffStart Element :firstnameFirst Name : yongEnd Element :firstnameStart Element :lastnameLast Name : mook kimEnd Element :lastnameStart Element :nicknameNick Name : mkyongEnd Element :nicknameStart Element :salarySalary : 100000End Element :salaryEnd Element :staffStart Element :staffStart Element :firstnameFirst Name : lowEnd Element :firstnameStart Element :lastnameLast Name : yin fongEnd Element :lastnameStart Element :nicknameNick Name : fong fongEnd Element :nicknameStart Element :salary

- 26 -

Page 27: Tratamiento de XML en Java

JAVA

Salary : 200000End Element :salaryEnd Element :staffEnd Element :company

- 27 -