|
Buscador
Secciones
Otras zonas
Registro
Foros
Recomendamos
|
Por ahora, simplemente estamos capturando cualquier excepción que el analizador pueda lanzar. Aprenderemos más sobre el precesamiento de errores en la sección Manejar Errores con el Analizador sin Validación.
|
|
Nota:
Aunque puede parecer un poco aburrido, llamaremos a nl() muchas veces dentro de nuestro código. Definirlo ahora simplificará el código posterior. También proporciona un lugar para indentar la salida cuando a esta sección del tutorial. |
Manejar Eventos de DocumentoFinalmente, escribiremos algo de código que realmente procesa los eventos DocumentHandler para los métodos añadidos. Añadimos el código en negrita de abajo para manejar los eventos start-document y end-document.
public void startDocument ()
throws SAXException
{
emit ("<?xml version='1.0' encoding='UTF-8'?>");
nl();
}
public void endDocument ()
throws SAXException
{
try {
nl();
out.flush ();
} catch (IOException e) {
throw new SAXException ("I/O error", e);
}
}
Aquí hemos mostrado una declaración XML cuando el analizador encuentra el inicio del documento. Como hemos configurado OutputStreamWriter para usar la codificación UTF-8, incluimos ésta especificación como parte de la declaración.
|
Nota:
Sin embargo, las clases IO no entienden los nombres de codificaciones con guiones, por eso debemos especificar "UTF8" en vez de "UTF-8". |
Al final del documento, simplemente poner una nueva línea y vaciamos el stream de salida. Añadimos el código en negrita de abajo para procesar los eventos start-element y end-element.
public void startElement (String name, AttributeList attrs)
throws SAXException
{
emit ("<"+name);
if (attrs != null) {
for (int i = 0; i < attrs.getLength (); i++) {
emit (" ");
emit (attrs.getName(i)+"=\""+attrs.getValue (i)+"\"");
}
}
emit (">");
}
public void endElement (String name)
throws SAXException
{
emit ("</"+name+">");
}
Con este código, mostramos las etiquetas de elementos, incluyen cualquier atributo definido en la etiqueta de inicio. Para finalizar esta versión del programa, añadimos el código en negrita de abajo para mostrar los caracteres que ve el analizador.
public void characters (char buf [], int offset, int len)
throws SAXException
{
String s = new String(buf, offset, len);
emit (s);
}
¡Felicidades! Hemos escrito un aplicación analizador SAX. El siguiente paso es compilarlo y ejecutarlo.
|
Nota:
Para estar seguros, el manejador de caracteres debería escanear el buffer para buscar caracteres ampersand ('&') y ángulos a la izquierda ('<') y reemplazarlos con los strings "&" o "<", según sea apropiado. Encontraremos más sobre estos tipos de procesamiento cuando expliquemos las referencias a entidades en Sustituir e Insertar Texto. |
Compilar el ProgramaPara compilar el programa que hemos creado, ejecutaremos el comando apropiado para nuestro sistema (o usaremos los scripts de comandos mencionados abajo).
Windows:
javac -classpath %XML_HOME%\jaxp.jar;%XML_HOME%\parser.jar Echo.java
Unix:
javac -classpath ${XML_HOME}/jaxp.jar:${XML_HOME}/parser.jar Echo.java
donde:
|
Nota:
Si estamos usando la versión 1.1 de la plataforma también necesitamos añadir %JAVA_HOME%\lib\classes.zip tanto para el script de compilación como el de ejecución, donde JAVA_HOME es la localización de la plataforma Java. |
Ejecutar el ProgramaPara ejecutar el programa, de nuevo ejecutamos los comandos apropiados para nuestro sistema.
Windows:
java -classpath .;%XML_HOME%\jaxp.jar;%XML_HOME%\parser.jar Echo slideSample.xml
Unix:
java -classpath .:${XML_HOME}/jaxp.jar:${XML_HOME}/parser.jar
Echo slideSample.xml
Scripts de ComandosPara hacernos la vida más fácil, aquí tenemos algunos scripts de comandos que podemos usar para compilar y ejecutar nuestras aplicaciones mientras trabajemos con este tutorial.
| Unix | Windows | |
|---|---|---|
| Scripts | constuir, ejecutar | build.bat, run.bat |
| Netscape | Pulsa, elige File-->Save As | Pulsa con el botón derecho, elige Save Link As. |
| Internet Explorer |
-/- | Pulsa con el botón derecho, elige Save Target As. |
Chequear la SalidaLa salida del programa es almacenada en Echo01-01.log. Aquí tenemos una parte de él, mostrando algo de su espaciado.
...
<slideshow title="Sample Slide Show" date="Date of publication"
author="Yours Truly">
<slide type="all">
<title>Wake up to WonderWidgets!</title>
</slide>
...
Mirando esta salida, nos surgen un buen número de preguntas. ¿De dónde vienen los espacios verticales extras? y ¿por qué estos elementos están identados apropiadamente, cuando el código no lo está? Bien, responderemos a estas preguntas en un momento. Primero hay unos cuantos puntos a observar sobre la salida.
<!-- A SAMPLE set of slides -->
No aparece en el lista. Los comentarios son ignorados por definición, a menos que implementemos un LexicalEventListener en lugar de un DocumentHandler.
Identificar los EventosEsta versión del programa echo podría ser útil para mostrar un fichero XML, pero no nos dice mucho sobre hacía donde va el analizador. El siguiente paso es modificar el programa para que podamos ver de dónde vienen los espacios y las líneas verticales.
|
Nota:
El código descrito en esta sección está en Echo02.java. La salida que produce está contenida en Echo02-01.log. |
Haremos los cambios en negrita que hay abajo para identificar los eventos cuando ocurran.
public void startDocument ()
throws SAXException
{
nl();
nl();
emit ("START DOCUMENT");
nl();
emit ("<?xml version='1.0' encoding='UTF-8'?>");
nl();
}
public void endDocument ()
throws SAXException
{
nl(); emit ("END DOCUMENT");
try {
...
}
public void startElement (String name, AttributeList attrs)
throws SAXException
{
nl(); emit ("ELEMENT: ");
emit ("<"+name);
if (attrs != null) {
for (int i = 0; i < attrs.getLength (); i++) {
emit (" ");
emit (attrs.getName(i)+"=\""+attrs.getValue (i)+"\"");
nl();
emit(" ATTR: ");
emit (attrs.getName (i));
emit ("\t\"");
emit (attrs.getValue (i));
emit ("\"");
}
}
if (attrs.getLength() > 0) nl();
emit (">");
}
public void endElement (String name)
throws SAXException
{
nl();
emit ("END_ELM: ");
emit ("</"+name+">");
}
public void characters (char buf [], int offset, int len)
throws SAXException
{
nl(); emit ("CHARS: |");
String s = new String(buf, offset, len);
emit (s);
emit ("|");
}
Compilamos y ejecutamos esta versión del programa para producir una salida más informativa. Los atributos se muestran uno por línea, que es más bonito. Pero, más importante, las líneas de salida se parecen a esta.
CHARS: |
|
vemos que el método characters es responsable de mostrar tanto los espacios que crean la identación y las múltiples nuevas líneas que separan los atributos.
|
Nota:
La especificación XML requiere que todos los separadores de líneas de entrada estén normalizados a una simple nueva línea. El carácter de nueva línea se especifica como \n en Java, C, y en sistemas Unix, pero tiene el alias "linefeed" en sistemas Windows. |
Comprimir la SalidaPara hacer la salida más leíble, modificamos el programa para que sólo muestre los caracteres que tienen algo distinto de los espacios en blanco.
|
Nota:
El código explicado en está sección está en Echo03.java. |
Haremos los cambios mostrados abajo para suprimir de la salida los caracteres que son espacios en blanco.
public void characters (char buf [], int offset, int len)
throws SAXException
{
nl(); emit ("CHARS: |");
nl(); emit ("CHARS: ");
String s = new String(buf, offset, len);
emit (s);
emit ("|");
if (!s.trim().equals("")) emit (s);
}
Si ejecutamos el programa ahora, veremos que hemos eliminado también toda la identación, porque el espacio de identación forma parte de los espacios en blanco que preceden el inicio del elemento. Añadimos el código en negrita de abajo para manejar la identación.
static private Writer out;
private String indentString = " "; // Amount to indent
private int indentLevel = 0;
...
public void startElement (String name, AttributeList attrs)
throws SAXException
{
indentLevel++;
nl(); emit ("ELEMENT: ");
...
}
public void endElement (String name)
throws SAXException
{
nl();
emit ("END_ELM: ");
emit ("</"+name+">");
indentLevel--;
}
...
private void nl ()
throws SAXException
{
...
try {
out.write (lineEnd);
for (int i=0; i < indentLevel; i++) out.write(indentString);
} catch (IOException e) {
...
}
Este código configura un string de identación, sigue la pista del nivel de identación actual, y saca el string de identación siempre que se llame al método nl.
Inspeccionar la SalidaLa salida completa para esta versión del programa está contenida en Echo03-01.log.
ELEMENT: <slideshow
...
CHARS:
CHARS:
ELEMENT: <slide
...
END_ELM: </slide>
CHARS:
CHARS:
Observa que el método characters fue invocado dos veces en una fila. Inspeccionando el fichero fuente slideSample01.xml veremos que hay un comentario antes de la primera diapositiva. La primera llamada a characters viene antes de este comentario. La segunda llamada viene después.
Observa, también, que el método characters es llamado después del primer elemento slide, así como antes de él. Cuando pensamos en términos de una estructura de datos del tipo árbol, parace obvio. Después de todo, queremos que el elemento slideshow contenga elementos slide, no texto.
En ausencia de un DTD, el analizador debe asumir que cualquier elemento que vea contiene texto como el del primer elemento del slide.
<item>Why <em>WonderWidgets</em> are great</item>
Aquí , la estructura de árbol se parece a esto.
ELEMENT: <item>
CHARS: Why
ELEMENT: <em>
CHARS: WonderWidgets
END_ELM: </em>
CHARS: are great
END_ELM: </item>
Documentos y DatosEn este ejemplo, está claro que hay una mezcla de caracteres con la estructura de los elementos. El hecho de que el texto pueda rodear los elementos nos ayuda a explicar porque algunas veces oímos hablar sobre "datos XML" y otras veces oímos hablar sobre "documentos XML". XML maneja confortablemente tanto estructuras de datos como documentos de texto que pueden incluir marcas. La única diferencia entre los dos es si se permite o no texto entre los elementos.
|
Nota:
En una futura sección de este tutorial, trabajeremos con el método ignorableWhitespace del interface DocumentHandler. Este método sólo puede invocarse cuando está presente un DTD. Si un DTD especifica que slideshow no contiene texto, entonces todos los espacios en blanco que rodean a los elementos slide son ignorables por definición. Por otro lado, si slideshow puede contener texto (lo que se debe asumir como verdadero en ausencia de un DTD), el analizador debe asumir que los espacios y líneas que ve entre los elementos slide son parte importante del documento. |
| Leer comentarios (25) | |
| Escribir comentario | |
| Puntuación: |
|
| Votar | |
| Recomendar este tutorial | |
| Estadísticas |
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