Ya hicimos un post acerca de leer ficheros XML. Esta vez nos vamos a centrar en leer ficheros XML que pueden llegar a ser demasiado grandes. Aunque ya indicamos que hacerlo con SAX era mejor que con DOM porque solo carga los elementos que lee en memoria, es posible que aun no sea suficiente. Para esta nueva forma usaremos XMLInputFactory.
El ejemplo es básicamente igual e incluso los métodos se parecen bastante por lo cual no será difícil de entender. El XML de ejemplo es:
Crearemos una clase que será la encargada de leer el ficheor XML y 'parsearlo'. Y que contiene los atributos necesarios para devolver una lista de libros en formato de objetos java.Las estrellas mi destino Alfred Bester ..... El juego de Ender Orson Scott Card
public class BigXmlOwnHandler { private Libro libro; private ListEl 'parseo' lo realizaremos en un método propio que denominamos parser:list; public List getList(){ return list; }
public void parser(final String absFilePath) throws FileNotFoundException, XMLStreamException { //Creamos el InputStream asociado al fichero pasado final FileInputStream in = new FileInputStream(absFilePath); //Creamos la factory que nos permite obtener el lector del XML final XMLInputFactory factory = XMLInputFactory.newInstance(); final XMLStreamReader parser = factory.createXMLStreamReader(in); //Iteramos por los eventos (elementos) del XML for (int event = parser.next(); event != XMLStreamConstants.END_DOCUMENT; event = parser.next()) { switch (event) { //Al comenzar un elemento vamos al metodo que contiene la logica necesaria para obtener la informacion case XMLStreamConstants.START_ELEMENT: startElement(parser); break; //Al acabar un elemento vamos al metodo que contiene la logica necesaria para almacenar la informacion case XMLStreamConstants.END_ELEMENT: endElement(parser); break; } } }En este caso, no se trata de sobrescribir métodos sino de iterar por los eventos (elementos) de un fichero XML. Para generar nuestra lista de libros nosotros solo necesitaremos realizar cierta lógica en los eventos START_ELEMENT y END_ELEMENT. A cada evento le asociamos un método propio que permite obtener y almacenar la información Evento STAR_ELEMENT, con este evento podemos ver que elemento vamos a leer y cual es la información que contiene.
public void startElement(final XMLStreamReader parser) throws XMLStreamException { //vamos a leer el elementoEvento END_ELEMENT, con este evento podemos ver que elemento acabamos de terminar de leer y almacenar la información.if ("libro".equals(parser.getLocalName())) { libro = new Libro(); //Iteramos por sus atributos para obtener el valor de las paginas for (int i = 0; i < parser.getAttributeCount(); i++) { final String localName = parser.getAttributeLocalName(i); final String value = parser.getAttributeValue(i); if ("paginas".equals(localName)) { libro.setPaginas(Integer.valueOf(value)); } } //vamos a leer el elemento y obtenemos su contenido con getElementText() } else if ("autor".equals(parser.getLocalName())) { libro.setAutor(parser.getElementText()); //vamos a leer el elemento y obtenemos su contenido con getElementText() } else if ("nombre".equals(parser.getLocalName())) { libro.setNombre(parser.getElementText()); } }
public void endElement(final XMLStreamReader parser) { if ('libro'.equals(parser.getLocalName())) { list.add(libro); } }Toda la lógica del método parser no es necesaria incluirla en una clase pero de esta forma encapsulamos la lógica que permite leer el fichero XML y lo tenemos todo un poco más ordenado. Con este método no necesitamos ninguna librería extra, y podemos usar esta solución a partir de la JDK 5
No hay comentarios:
Publicar un comentario