Parsear un XML con SAX

2055 vistas

Imaginemos el fichero XML siguiente que representa una agenda:



xml
  1. <agenda>
  2.   <persona id="0">
  3.       <nombre>nombre0</nombre>
  4.       <apellido>apellido0</apellido>
  5.       <direccion>direccion0</direccion>
  6.   </persona>
  7.   <persona id="1">
  8.       <nombre>nombre1</nombre>
  9.       <apellido>apellido1</apellido>
  10.       <direccion>direccion1</direccion>
  11.   </persona>
  12. </agenda>



Veamos un sencillo JavaBean Persona que nos permita representar una entrada en esta agenda:



java
  1. public class Persona{
  2.   private int id;
  3.   private String nombre, apellido, direccion;
  4.   public Persona(){}
  5.   public int getId(){return id;}
  6.   public String getNombre(){return nombre;}
  7.   public String getApellido(){return apellido;}
  8.   public String getDireccion(){return direccion;}
  9.   public void setId(int id){this.id = id;}
  10.   public void setNombre(String nombre){this.nombre = nombre;}
  11.   public void setApellido(String apellido){this.apellido = apellido;}
  12.   public void setDireccion(String direccion){this.direccion = direccion;}
  13.   public String toString(){
  14.       return new StringBuffer("Nombre: ").append(nombre).append(", ")
  15.       .append("Apellido: ").append(apellido).append(", ")
  16.       .append("Dirección: ").append(direccion)
  17.       .toString();
  18.   }
  19. }



Ahora veamos el DefaultHandler que nos permita el parsing del XML. El parsing simplemente recuperará una List de Persona.



java
  1. public class PersonaHandler extends DefaultHandler{
  2.   // resultados de nuestro parser
  3.   private List<Persona> agenda;
  4.   private Persona persona;
  5.   // flags que nos indicarán la posición del parser
  6.   private boolean inAgenda, inPersona, inNombre, inApellido, inDireccion;
  7.   // buffer que nos permitirá recuperar los datos
  8.   private StringBuffer buffer;
  9.   // constructor
  10.   public PersonaHandler(){
  11.       super();
  12.   }
  13.   // detección de obertura de etiqueta
  14.   public void startElement(String uri, String localName,
  15.                         String qName, Attributes attributes) throws SAXException{
  16.       if(qName.equals("agenda")){
  17.         agenda = new LinkedList<Persona>();
  18.         inAgenda = true;
  19.       }else if(qName.equals("persona")){
  20.         persona = new Persona();
  21.         try{
  22.             int id = Integer.parseInt(attributes.getValue("id"));
  23.             persona.setId(id);
  24.         }catch(Exception e){
  25.         // error, el contenido de Id no es un entero
  26.             throw new SAXException(e);
  27.         }
  28.         inPersona = true;
  29.       }else {
  30.         buffer = new StringBuffer();
  31.         if(qName.equals("nombre")){
  32.             inNombre = true;
  33.         }else if(qName.equals("apellido")){
  34.             inApellido = true;
  35.         }else if(qName.equals("direccion")){
  36.             inDireccion = true;
  37.         }else{
  38.             // error, provocamos excepción
  39.             throw new SAXException("Etiqueta "+qName+" desconocida.");
  40.         }
  41.       }
  42.   }
  43.   // detección fin etiqueta
  44.   public void endElement(String uri, String localName, String qName)
  45.                 throws SAXException{
  46.       if(qName.equals("agenda")){
  47.         inAgenda = false;
  48.       }else if(qName.equals("persona")){
  49.         agenda.add(persona);
  50.         persona = null;
  51.         inPersona = false;
  52.       }else if(qName.equals("nombre")){
  53.         persona.setNombre(buffer.toString());
  54.         buffer = null;
  55.         inNombre = false;
  56.       }else if(qName.equals("apellido")){
  57.         persona.setApellido(buffer.toString());
  58.         buffer = null;
  59.         inApellido = false;
  60.       }else if(qName.equals("direccion")){
  61.         persona.setDireccion(buffer.toString());
  62.         buffer = null;
  63.         inDireccion = false;
  64.       }else{
  65.         // error, provocamos excepción
  66.         throw new SAXException("Etiqueta "+qName+" desconocida.");
  67.       }         
  68.   }
  69.   // detección de carácteres
  70.   public void characters(char[] ch,int start, int length)
  71.                 throws SAXException{
  72.       String lectura = new String(ch,start,length);
  73.       if(buffer != null) buffer.append(lectura);
  74.   }
  75.   // inicio parsing
  76.   public void startDocument() throws SAXException {
  77.     System.out.println("Inicio parsing");
  78.   }
  79.   // fin parsing
  80.   public void endDocument() throws SAXException {
  81.     System.out.println("Fin parsing");
  82.     System.out.println("Resultados del parsing");
  83.     for(Persona p : agenda){
  84.         System.out.println(p);
  85.     }
  86.   }
  87. }



El uso de estos tres elementos se hace sencillamete asÃ:



java
  1.   SAXParserFactory factory = SAXParserFactory.newInstance();
  2.   SAXParser parser = factory.newSAXParser();
  3.   File fichero = new File("./EjemploSAX.xml");
  4.   DefaultHandler handler = new PersonaHandler();
  5.   parser.parse(fichero, handler);