Zona HTML Zona Java Zona PHP Zona ASP Zona Bases de datos
-Tutoriales

El API JAXP


LexicalEventListener

Vimos anteriormente que si estamos escribiendo texto como XML, nocesitamos conocer si estamos en una sección CDATA. Si lo estamos, los ángulos (<) y ampersands (&) deberían salir sin modificar. Pero si no estamos en una sección CDATA, deberían ser reemplazados por las entidades predefinidas &lt; y &amp;. ¿Pero, cómo sabemos si estamos procesando una sección CDATA?

De la misma forma, si estamos filtrando XML de alguna forma, querríamos pasar también los comentarios. Normalmente el analizador ignora los comentarios. ¿Cómo podemos obtener los comentarios para poder sacarlos por la salida?

Finalmente, están las definiciones de entidades del analizador. Si una aplicación de filtrado XML vee una &myEntity; necesita sacar la misma cadena -- no el texto que se inserta en su lugar. ¿Cómo podemos hacer esto?

Esta página del tutorial responde estas preguntas. Muestra cómo usar com.sun.xml.parser.LexicalEventListener para identificar comentarios, secciones CDATA y referencias a entidades del analizador

  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.

Los comentarios, las etiquetas CDATA, y las referencias a entidades del analizador constituyen információn léxica -- es decir, información que concierte al texto del propio XML, en vez de a la información contenida en el XML. Por supuesto, a muchas aplicaciones, sólo les importa el contenido de un documento XML. Dichas aplicaciones no usarán el API LexicalEventListener. Pero las aplicaciones que sacan texto XML lo encontrarán muy útil.

Nota:

El API LexicalEventListener será parte de la especificación SAX 2.0.

. Cómo Funciona LexicalEventListener

Para ser informados cuando el analizador SAX ve información léxica, configuramos el analizador con un LexicalEventListener en vez de un DocumentHandler. El interface LexicalEventListener extiende el interface DocumentHandler para añadirle.

  • comment(String comment)
    Pasa comentarios de la aplicación.

  • startCDATA(), endCDATA()
    Dicen cuando empieza y termina una sección CDATA, lo que le dice a nuestra aplicación que clases de caracteres puede esperar la próxima vez que se llame a characters().

  • startParsedEntity(String name), EndParsedEntity(String name, Boolean included)
    Obtienen el nombre de una entidad de analizador. El valor booleano included dice si el valor de la entidad fue pasado a la aplicación. Aunque los analizadores con validación tienen que procesar entidades externas, la especificación permite a los analizadores sin validación saltarselas. Este valor nos dice si el analizador sin validación lo hizo o no.

. Trabajar con un LexicalEventListener

En el resto de esta página, convertiremos la aplicación Echo en un oyente de eventos léxicos y jugaremos con sus características.

Nota:

El código mostrado aquí está en Echo11.java. Y la salida está en Echo11-09.log.

Para empezar, añdimos el código en negrita de abajo para implementar el interface LexicalEventListener y añadir los métodos apropiados.

import com.sun.xml.parser.LexicalEventListener;

public class Echo extends HandlerBase
   implements LexicalEventListener
{ 
    ...
        public void processingInstruction (String target, String data)
      ...
    }
     
    public void comment(String text)
              throws SAXException
    {
    }

    public void startCDATA()
              throws SAXException
    {
    }

    public void endCDATA()
              throws SAXException
    {
    }

    public void startParsedEntity(String name)
              throws SAXException
    {
    }

    public void endParsedEntity(String name,
                                boolean included)
              throws SAXException
    {
    }

  private void emit (String s)
    ...

Estos son los únicos cambios que necesitamos hacer para convertir la clase Echo en un oyente de eventos léxicos. El analizador chequea el tipo de la clase, y sabe que el "document handler" que especificamos con:

parser.setDocumentHandler ( new Echo() );

es realmente la clase extendida LexicalEventListener.

. Sacar Comentarios

El siguiente paso es hacer algo con uno de los nuevos métodos. Añadimos el código en negrita de abajo para mostrar los comentarios del fichero XML:

    public void comment(String text)
              throws SAXException
    {
       nl(); emit ("COMMENT: "+text);
    }

Cuando compilamos el programa Echo y lo ejecutamos sobre nuestro fichero XML, el resultado se parece a esto:

COMMENT:  A SAMPLE set of slides  
COMMENT:  
    DTD for a simple "slide show".
COMMENT:  Defines the %inline; declaration 
COMMENT:  ...

Los finales de línea en los comentarios son pasados como parte de la cadena de comentarios, normalizados a nuevas líneas (\n). También podemos ver que los comentarios en el DTD son mostrados junto con los comentarios del fichero. (Esto puede crear algún problema cuando queremos mostrar sólo los comentarios del fichero de datos. Para resolver este problema, usamos los métodos startDTD y endDTD del interface DtdEventListener.)

. Mostrar Otra Información Léxica

Para finalizar esta sección, ejercitaremos los métodos restantes de LexicalEventHandler.

Nota:

El código de está sección está en Echo12.java. El fichero sobre el que opera es slideSample10.xml. Y la salida está en Echo12-10.log.

Hacemos los cambios en negrita de abajo para eliminar la visualización de comentarios y mostrar los otros eventos.

public void comment(String text)
     throws SAXException
{

  nl(); emit ("COMMENT: "+text);
}

public void startCDATA()
      throws SAXException
{
  nl(); emit ("START CDATA SECTION");
}

public void endCDATA()
      throws SAXException
{
  nl(); emit ("END CDATA SECTION");
}

public void startParsedEntity(String name)
               throws SAXException
{
  nl(); emit ("START PARSED ENTITY: "+name);
}

public void endParsedEntity(String name,
                    boolean included)
             throws SAXException
{
  nl(); emit ("END PARSED ENTITY: "+name);
  emit (", INCLUDED="+included);
}

Aquí vemos lo que sucede cuando la entidad interna products es procesada con la última versión del programa:

ELEMENT: <slide-title>
CHARS:   Wake up to 
START PARSED ENTITY: products
CHARS:   WonderWidgets
END PARSED ENTITY: products, INCLUDED=true
CHARS:   !
END_ELM: </slide-title> 

Y aquí está el resultado del procesamiento de la entidad externa copyright:

            START PARSED ENTITY: copyright
            CHARS:   
This is the standard copyright message ...
            END PARSED ENTITY: copyright, INCLUDED=true

Finalmente, obtenemos una salida como está para la sección CDATA:

START CDATA SECTION
CHARS:   Diagram.
         
frobmorten <------------ fuznaten
   |            <3>        ^
   | <1>                   |   <1> = fozzle
   V                       |   <2> = framboze    
staten --------------------+   <3> = frenzle
            <2>

END CDATA SECTION

En suma, el LexicalEventListener nos ofrece las notificaciones de eventos que necesitamos para producir una copia segura del texto XML original.

 
Patrocinados
 

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

Hospedaje web y servidores dedicados linux por Ferca Network