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:
- Modificar un programa que lee datos y los modifica para generar eventos SAX.
- Con el analizador SAX a mano, conectaremos con un constructor de documento para crear un DOM.
- 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!
Nota: