(Anterior) DOM, SAX y JDOM

Procesar XML con SAX

El siguiente programa toma como parámetro un archivo XML y lo imprime a pantalla, aunque es sumamente sencillo ejemplifica el uso de eventos para SAX, una vez entendido su uso , es relativamente fácil modificar las funciones de eventos para que estas realizan otra labor y no simplemente imprimir a pantalla.

El siguiente ejemplo esta basado en el parser Xerces 2.0, sin embargo, se hace uso de las librerías JAXP por lo que puede ser ejecutado en otro parser Java sin complicaciones.

Dentro de este programa se definen TODOS los eventos de SAX disponibles,sin embargo, esto no es absolutamente necesario, inclusive debido a que este programa hereda ("inherit") el comportamiento de DefaultHandler (la clase base de SAX) ya se encuentran definidos comportamientos default.

Lo que se esta realizando es conocido en el mundo Java como override, esto es, alterar el comportamiento de funciones ya definidas, imprimiendo mensajes más descriptivos.

package com.osmosislatina.xml.sax;

// Librerías de I/O 
import java.io.*;

// Librerías de SAX 
import org.xml.sax.*;
import org.xml.sax.helpers.*;

// Clases JAXP 
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.ParserConfigurationException;


public class EventosSAX extends DefaultHandler {
    //
    // Metodos del DefaultHandler que son reimplementados ("overriden")
    //

    /** Evento Instrucciones de Procesamiento . */
    public void processingInstruction(String target, String data) 
    throws SAXException {
	nl();
	emit ("<?"+target+" "+data+"?>");
    } // Termina Instrucciones de Procesamiento


    /** Evento Inicio de Documento . */ 
    public void startDocument() 
    throws SAXException {
	nl();
	nl();
	emit("INICIO DOCUMENTO");
	nl();
	emit ("<?xml version='1.0' encoding='UTF-8'?>");

    } // Termina Inicio de Documento 


    /** Evento Fin de Documento. */ 
    public void endDocument()  
    throws SAXException {
	nl(); 
	emit ("TERMINA DOCUMENTO");
	try { 
	    nl();
	    out.flush();
	} catch (IOException e) { 
	    throw new SAXException ("I/O Error", e);
	}

    } // Termina Fin de Documento 


    /** Evento Inicio de Elemento . */
    public void startElement(String uri, String local, String name,
                             Attributes attrs)  
			     throws SAXException {

        nivelSangria++;
        nl(); 
	emit ("ELEMENTO: ");
        emit ("<"+name);
        if (attrs != null) {
            for (int i = 0; i < attrs.getLength (); i++) {
                nl();
                emit("Atributo: ");
                emit (attrs.getQName (i));
                emit (" /  Valor: ");
                emit (attrs.getValue (i));
                emit ("\"");
            }
        }
        if (attrs.getLength() > 0) nl();
        emit (">");
    } // Termina Inicio de Elemento 

    /** Evento  de Caracteres. */
    public void characters(char buf[], int offset, int len) 
    throws SAXException {

        nl(); emit ("Contenido (crudo) :   ");
        String s = new String(buf, offset, len);
        if (!s.trim().equals("")) emit (s);

    } // Termina metodo Caracteres


    /** Evento de whitespace. */
    public void ignorableWhitespace(char buf[], int offset, int len) 
     throws SAXException {

   nl(); emit("<<<<ESPACIO EN BLANCO>>>>>");
    } // Termina Whitespace 

    /** Evento de Terminacion del Elemento . */
    public void endElement(String uri, String local, String name) 
    throws SAXException {
        nl();
        emit ("TERMINA ELEMENTO: ");
        emit ("</"+name+">");
        nivelSangria--;
    } // Evento de Terminacion del Elemento

    //
    // Metodos para Errores en SAX 
    //

    /** Evento  de Warning. */ 
    public void warning(SAXParseException err) 
    throws SAXException {
        System.out.println ("** Peligro: "
            + ", line " + err.getLineNumber ()
            + ", uri " + err.getSystemId ());
        System.out.println("   " + err.getMessage ());
    } // Termina Warning 

    /** Evento de Error. */ 
    public void error(SAXParseException e) 
    throws SAXException {
        throw e;
    } // Termina Error

    /** Evento de Error Fatal */ 
    public void fatalError(SAXParseException ex) 
    throws SAXException {
        System.err.println("[Error Fatal] "+
                           ex.getMessage());
        throw ex;
    } // Termina Error Fatal

Una vez definidos los eventos SAX, se define el método principal de ejecución main donde es configurado y creada la instancia del parser para procesar la información del archivo; en este programa particular se definen dos métodos adicionales los cuales funcionan como auxiliares a los eventos SAX.

    //
    // Programa Principal 
    //


    // Variables 
    static private Writer out;
    private String sangria = "     "; // Tamaño de Sangria
    private int nivelSangria = 0;

      /**  Inicio Programa Principal  */
    public static void main(String args[]) {

        // Revisar que exista un archivo de entrada 
        if (args.length != 1) {
         System.out.println("Debe indicar un archivo XML 
                                             para ser procesado");
         System.exit(1);
        }
	
	// Crear la fabrica utilizar para SAX 
	
	SAXParserFactory factory  = SAXParserFactory.newInstance();
	
	try { 
	    // Generar el Stream para enviar a Pantalla

	    out = new OutputStreamWriter (System.out, "UTF8");
	    
	    // Procesar archivo 
	    SAXParser saxParser = factory.newSAXParser();
	    saxParser.parse( new File(args[0]), new EventosSAX() );

	} catch (ParserConfigurationException pexc) { 
	    pexc.printStackTrace();
	} catch (SAXException saxex) { 
	    saxex.printStackTrace();
	} catch (IOException ioe) { 
	    // I/O Error 
	    ioe.printStackTrace();
	}
	System.exit(0);

    }

    // Metodos auxiliares utilizados para no abrumar fuciones de Eventos SAX
    
    private void emit(String s) 
    throws SAXException 
    { 
	try { 
	    out.write(s);
	    out.flush();
	} catch (IOException e) { 
	    throw new SAXException ("Error I/O", e);
	}
    }
	
    private void nl() 
    throws SAXException 
    {
	String lineEnd = System.getProperty("line.separator");
	try { 
	    out.write (lineEnd);
	    for (int i=0; i < nivelSangria; i++) out.write(sangria);
	} catch (IOException e) { 
	    throw new SAXException ("Erro I/O", e);
	}
    }

}

Menú Curso

XML y sus Orígenes

Manipulación y Proceso de XML

DOM, SAX y JDOM

Namespaces, Schemas y DTD's

XSL: XSLT, XPath y TraX

XMLRPC y SOAP (Web Services)

Diseño con XMLRPC

Diseño con SOAP .

Apéndice "A" (Procesando XML con parsers).

Apéndice "B" (Validando XML con Schemas y DTD's).

Apéndice "C" (XSL: XPath y "XSL Stylesheets").

Apéndice "D" (XMLRPC: Diseño).

Apéndice "E" (SOAP, WSDL, UDDI y WSIL : Diseño).