Programación en castellano
Inicio > Tutoriales > Java y XML > El API JAXP
-Tutoriales

El API JAXP


Generar una Estructura de Datos Arbitraria

En la última página, vimos cómo nuestro conocimiento del análisis de SAX era muy útil cuando teníamos errores del analizador. En esta sección, usaremos este conocimiento para simplificar los procesos para convertir un estructura de datos arbitraria en XML.

Nota:

Este material es específico de Project X, la implementación de referencia de Sun. El material de esta sección no forma parte del estándard. En su lugar, representa funcionalidades útiles que podríamos necesitar para aprovecharnos hasta que se haya estandarizado algún mecanismo equivalente. Como no forma parte del estándard JAXP, las funcionalidades descritas aquí podrían muy bien no existir en otros analizadores estándards JAXP.

. ¿Cómo Funciona?

Recordamos de La Implementación de Referencia "Project X" que la implementación de referencia de Sun para el API JAXP usa un analizador SAX para leer los datos XML cuando se construye un DOM. En esta sección, veremos cómo aprovecharnos de este echo para convertir un conjunto de datos existentes en XML.

En genaral, vamos a ir a:

  1. Modificar un programa que lee datos y los modifica para generar eventos SAX.
  2. Con el analizador SAX a mano, conectaremos con un constructor de documento para crear un DOM.
  3. Usaremos el método write de la implementación de referencia para producir XML.

Hemos asumido que tenemos algún programa que puede leer los datos. Asumiendo que tenemos un conjunto de datos que queremos convertir, es bueno tener alguna aplicación que pueda leerlos. El Analizador empieza en este punto.

. Modificar el "Analizador" para Generar Eventos SAX

El siguiente paso es modificar el analizador para generar eventos SAX. Empezamos extendiendo javax.xml.parsers.SAXParser.

Generar un evento SAX significa invocar a uno de los métodos de org.xml.sax.DocumentHandler. Vimos muchos de estos métodos en Mostrar un Fichero XML con el Analizador SAX y Añadir Manejadores de Eventos Adicionales. Aquí tenemos el mínimo conjunto de eventos que el analizador necesita generar para algunos DocumentHandler, d:

d.startDocument()
d.endDocument()
d.startElement(String name, AttributeList attrs)
d.endElement(String name)
d.characters(char buf [], int offset, int len)
Nota:

Como cada uno de estos métodos puede lanzar una SAXException, el analizador tendrá que estar preparado para manejarlas.

Aquí están los eventos DocumentHandler que normalmente queremos ignorar:

setDocumentLocator(Locator l)
ignorableWhitespace(char buf [], int offset, int len)
processingInstruction(String target, String data) 

El fichero de datos no tiene que procesar las instrucciones, por eso es fácil ver porque ignoramos éste. Y ignorableWhitespace genera exactamente el mismo XML que la antigua llamada a characters, por eso éste también puede ser ignorado. Lo que nos deja setDocumentLocator.

El evento setDocumentLocator es sólo útil para una aplicación que vaya a interpretar los datos en un fichero XML, identificar un nombre de fichero relativo a la localización actual, y recuperar este fichero. Pero los eventos generados por nuestro analizador no tienen nada que ver con dicho proceso -- ellos van a un DocumentHandler, que construirá un árbol DOM usando nuestros datos.

. Implementar el Interface org.xml.sax.Parser

Una vez que el analizador puede generar eventos SAX, necesita poder decirle dónde enviarlos. Para hacer esto, debe implementar el interface org.xml.sax.Parser y, como mínimo definir el método setDocumentHandler() con un implementación no nula.

Aquí tenemos una lista de los métodos de este interface. Podríamos elegir proporcionar implementaciones nulas para muchos de ellos, pero podríamos elegir implementar algunas, como setErrorHandler, en el interés de crear una aplicación más robusta.

parse(InputSource source) 
parse(java.lang.String systemId) 
setDocumentHandler(DocumentHandler handler) 
setDTDHandler(DTDHandler handler) 
setEntityResolver(EntityResolver resolver) 
setErrorHandler(ErrorHandler handler) 
setLocale(java.util.Locale locale)

. Conectar nuestro Analizador a un XmlDocumentBuilder

Luego usamos el código de abajo para conectar nuestro analizador SAX con un constructor de documentos, y procedemos a analizar los datos. (El código en negrita muestra las partes específicas de Sun).

import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;

import org.xml.sax.Parser;
import com.sun.xml.parser.Resolver;

import javax.xml.parsers.DocumentBuilder;
import com.sun.xml.tree.XmlDocumentBuilder;
import com.sun.xml.tree.XmlDocument;

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
Parser parser = saxParser.getParser();
builder = new XmlDocumentBuilder();
builder.setIgnoringLexicalInfo(true); // Skip comments, entity refs, etc.
parser.setDocumentHandler(builder); 
parser.parse(Resolver.createInputSource(new File(argv[0])));
XmlDocument document = builder.getDocument();

En este código, obtenemos un ejemplar de nuestra factoría de analizadores SAX, usamos esto para obtener nuestro analizador, y luego creamos un ejemplar del XmlDocumentBuilder de la implementación de referencia. Esta clase implementa el interface DocumentHandler, que nos permite conectarlo a nuestro analizador.

Luego invocamos al método parse del analizador, asumiendo que lo hemos implementado, o cualquier método que lo dispare. Como analiza lo datos, también genera eventos SAX. El XmlDocumentBuilder reacciona a dichos eventos y construye un DOM en el proceso. Recuperamos este DOM con el método getDocument, especificando el nombre de la clase (XmlDocument) en vez del interface general (Document) por eso podemos utilizar los métodos de salida de XmlDocument.

. Escribir la Salida

Como el último paso de nuestro programa, escribimos el DOM como un documento XML usando el método write de XmlDocument que aprendimos en la página anterior.

. Ejecutarlo

Finalmente, especificamos el path completo de nuestra factoria de analizadores en la línea de comandos como una propiedad del sistema, usando la bandera -D, de esta forma:

-Djavax.xml.parsers.SAXParserFactory=fully.qualified.name.of.parserFactory

Ahora, ejecutamos la aplicación. ¡Felicidades! hemos convertido con éxito una estructura de datos en XML con un esfuerzo mínimo. Bien, ok. Fue un gran esfuerzo, pero lo hicimos!

 
Patrocinados
 

Copyright © 1999-2007 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad

Hospedaje web y servidores dedicados linux por Ferca Network

red internet: musica mp3 | logos y melodias | hospedaje web linux | registro de dominios | servidores dedicados
más internet: comprar | recursos gratis | posicionamiento en buscadores | tienda virtual | gifs animados