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); } } } |
template
, XPath, Condicionales y Ciclos en XSL.