En este ejemplo se trata de procesar el XML que define un libro:
<?xml version="1.0" encoding="UTF-8"?>
<libro isbn="978-84-8346-520-2">
<titulo>El Ocho</titulo>
<autor>Katherine Neville</autor>
<anyo>1988</anyo>
<editorial>Ballantine Books</editorial>
</libro>
Usaremos un manejador de eventos específico para este XML. Esta clase recibirá en el constructor un objeto de la clase Libro, en el cual se almacenará la información leida del XML.
Guardaremos en una variable lo último que se haya leído en el método characters y en el evento de fin de etiqueta, endElement, guardaremos este valor en la propiedad correspondiente del objeto libro.
Puesto que el ISBN nos viene en un atributo tendremos que procesarlo en el evento startElement de la etiqueta libro.
ManejadorLibro.java
package es.latascadexela.xml.sax;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Clase que procesa los eventos SAX al leer el xml de un libro.
* Guardará todos los datos obtenidos del xml en el objeto libro,
* el cual se pasa en el constructor.
*
* @author Xela
*
*/
public class ManejadorLibro extends DefaultHandler{
private String valor = null;
private Libro libro;
public ManejadorLibro(Libro libro){
this.libro=libro;
}
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// Limpiamos la variable temporal.
valor=null;
// Si la etiqueta es libro leemos el atributo isbn
if(localName.equals("libro")){
String isbn = attributes.getValue("isbn");
// Lo guardamos en el objeto libro
libro.setIsbn(isbn);
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// Guardamos el texto en la variable temporal
valor = new String(ch,start,length);
}
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
// Según la etiqueta guardamos el valor leido
// en una propiedad del objeto libro
if (localName.equals("titulo")){
libro.setTitulo(valor);
}else if (localName.equals("autor")){
libro.setAutor(valor);
}else if (localName.equals("anyo")){
libro.setAnyo(valor);
}else if (localName.equals("editorial")){
libro.setEditorial(valor);
}
}
}
Una vez tenemos construido el manejador, tendremos que crear la clase que procesa el XML utilizando nuestro manejador.
ProcesaLibro.java
package es.latascadexela.xml.sax;
import java.io.FileInputStream;
import java.io.IOException;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
/**
* Clase que procesa un XML de un libro mediante el handler SAX ManejadorLibro
*
* @author Xela
*
*/
public class ProcesaLibro {
public static void main(String[] args) {
try {
// Creamos nuestro objeto libro vacío
Libro libro = new Libro();
// Creamos la factoria de parseadores por defecto
XMLReader reader = XMLReaderFactory.createXMLReader();
// Añadimos nuestro manejador al reader pasandole el objeto libro
reader.setContentHandler(new ManejadorLibro(libro));
// Procesamos el xml de ejemplo
reader.parse(new InputSource(new FileInputStream("/ruta_hasta_fichero/libro.xml")));
// Ya tenemos nuestro objeto libro con los valores obtenidos del xml
// Lo imprimimos
System.out.println(libro.toString());
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Por último, la clase entidad que almacena los datos de un libro.
Libro.java
package es.latascadexela.xml.sax;
/**
* Clase que almacena los datos de un libro
*
* @author Xela
*
*/
public class Libro {
private String isbn = null;
private String titulo = null;
private String autor = null;
private String anyo = null;
private String editorial = null;
// Constructor por defecto
public Libro() {
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getAutor() {
return autor;
}
public void setAutor(String autor) {
this.autor = autor;
}
public String getAnyo() {
return anyo;
}
public void setAnyo(String anyo) {
this.anyo = anyo;
}
public String getEditorial() {
return editorial;
}
public void setEditorial(String editorial) {
this.editorial = editorial;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("\nISBN: "+isbn);
sb.append("\nTítulo: "+titulo);
sb.append("\nAutor: "+autor);
sb.append("\nAño: "+anyo);
sb.append("\nEditorial: "+editorial);
return sb.toString();
}
}
Al ejecutar el main tenemos que el objeto libro tiene toda la información obtenida del XML. Puesto que lo hemos imprimido por la salida estándar obtendríamos lo siguiente:
ISBN: 978-84-8346-520-2
Título: El Ocho
Autor: Katherine Neville
Año: 1988
Editorial: Ballantine Books
Espero que os haya aclarado algo.
10 comentarios:
No falta la clase del objeto libro ?
Pues tienes toda la razón. Se me olvidó ponerla. Ahí la tienes.
Muchas gracias por la apreciación.
Despues de mirarme muchos tutoriales sobre SAX para hacer 4 chorradas para una practica de la universidad, encontre que este era el mas conciso y el mas claro para los que necesitamos parsear un simple XML.
Enhorabuena por el tutorial.
Muchas gracias, Gon.
Se agradecen comentarios como este. ;-)
Excelente articulo!, despues de horas de busqueda, este fue el unico que aclaró mis dudas.
Muy bien explicado a mis alumnos en la universidad siempre les indico tu blog.
Felicitactiones.
Hola Xela,
creo que existe un error en la clase Libro, concretamente en el método toString, ya que a la hora de llamar al método append del StringBuilder, pones \\n y eso Java lo toma como el caracter de escape \ y el salto de línea se lo come, por lo tanto, cuando se imprime por la salida estándar pone: \nISBN: .... \nTítulo: ... etc.
Un Saludo.
Muchas gracias, Jacinto. Corregido queda.
Saludos.
buen dia, me llamo william y tengo una duda:
como hago para leer varios libros, porque ahi esta claro para uno solo, pero cuando se tienen bastantes
¿como se hace?
¿en donde se modifica?
grax por la info y muy buen post
Hey!! felicitaciones.. después de dar muchas vueltas al fin encuentro un tuto decente que explique lo que se necesita saber.
Regards.
Publicar un comentario