Buscar
Social
Ofertas laborales ES
sábado
jun162001

Jext 3.0 un sencillo pero potente editor para prog

Jext es un editor opensource 100% Java hecho y pensado por programadores para programar. Podrás usar el mismo editor para programar en multitud de lenguajes (Java, C/C++, Perl, PHP, HTML, etc.) mostrándose en todos ellos sintaxis específica coloreada, podrás personalizarlo, extenderlo, e incluso comprimir tus ficheros en formato zip y mandarlos por email directamente desde el editor.
Lamentablemente es solo un editor, y aunque tiene un emulador de consola integrado, no llega a ser un entorno de desarrollo.
sábado
jun162001

Llega Cocoon 2

Llega Coocon 2, la nueva versión, totalmente reescrita con un mejor diseño, de este popular framework 100% Java para la publicación de contenido para la web basados en XML/XSLT. Separando un documento web en contenido, estilo y logica, se puede conseguir un sistema lo más adaptable posible para la publicación de información.
viernes
jun012001

Log4java (Parte 1)

Introducción a log4j.




Log4j ha sido elegido recientemente finalista en la categoría de "API/Tecnología Java nueva o revisada más útil." de los JavaWorld Editors' Choice Awards, que podrían equipararse a los Oscar del mundo Java.



Desde javaHispano queremos acercarte este API que te sorprenderá tanto por su sencillez, como por su potencia.



¿Qué es Log4j y dónde puedo encontrarlo?



Log4j es un API para manejar el registro (log) de operaciones en nuestros programas, que tan necesario resulta en los períodos de depuración. Log4j es uno de los componentes del proyecto Jakarta (al igual que Tomcat) de Apache, cuya página web principal es: http://jakarta.apache.org/log4j/



¿Cómo funciona Log4j?



En primer lugar, debemos saber que el API nos ofrece cinco prioridades diferentes, que de mayor a menor son: DEBUG, INFO, WARN, ERROR, FATAL, aunque de ser necesario también es posible crear nuestras propias prioridades.



De manera similar a la estructuración en paquetes de Java, Log4j divide los tipos de registro por categorías, cuya prioridad es hereditaria. Por ejemplo, si no definimos una prioridad para la categoría "com.javahispano.prueba", heredaría la prioridad de "com.javahispano". De esta forma, una vez definida una categoría, podemos enviar peticiones de registro (log requests) utilizando los métodos que ésta nos ofrece.



Para determinar la información que acompaña a nuestros mensajes, Log4j nos ofrece los Layouts. Entre ellos tenemos el SimpleLayout, que simplemente muestra la prioridad y el mensaje, u otros más elaborados como PatternLayout que nos deja formatear con total libertad la información que podemos mostrar de entre toda la que nos permite Log4j.



Para configurar el registro en general disponemos de tres opciones, las clases BasicConfigurator, PropertyConfigurator y DOMConfigurator. La primera utiliza un Layout predefinido para ir mostrando el registro por pantalla. Con las otras dos podremos usar un fichero de configuración normal para la primera, y un fichero XML ya parseado para la segunda.



Finalmente, para determinar lo que Log4j debe de hacer con la información del registro, están los Appenders. Entre estos disponemos de una gran variedad, que cubrirá casi con toda seguridad todas sus necesidades. Podemos escribir en un OutputStream con WriterAppender, en ficheros con FileAppender, en ficheros de registro de como máximo un tamaño con RollingFileAppender, podemos enviar por correo la información con SMTPAppender, o registrarle en un servidor especial para Log4j, cuyas clases por supuesto se incluyen, con SocketAppender, o incluso a un daemo syslog con SyslogAppender. No sólo eso, también se pueden enviar a varios sitios a la vez, con lo que las posibilidades son tremendas.



Un ejemplo básico (extraído de la documentación).




import com.foo.Bar;

// Importar las clases de log4j.
import org.apache.log4j.Category;
import org.apache.log4j.BasicConfigurator;

public class MyApp {

// Define una variable estática de categoría que referencia
// a la instancia de Category llamada "MyApp"
static Category cat = Category.getInstance(MyApp.class.getName());

public static void main(String[] args) {
// Configuración básica que imprime en la consola
BasicConfigurator.configure();
cat.info("Entrando en la aplicación.");
Bar bar = new Bar();
bar.doIt();
cat.info("Saliendo de la aplicación.");
}
}



La clase com.foo.bar:



package com.foo;

import org.apache.log4j.Category;

public class Bar {
static Category cat = Category.getInstance(Bar.class.getName());

public void doIt() {
cat.debug("Hazlo de nuevo!");
}
}



Al ejecutar MyApp, la salida sería:



0 [main] INFO MyApp - Entrando en la aplicación.
36 [main] DEBUG com.foo.Bar - Hazlo de nuevo!
51 [main] INFO MyAqpp - Saliendo de la aplicación.


Próximo artículo.



En el próximo artículo veremos el PatternLayout que se utiliza en BasicConfigurator para obtener esta salida, y aprenderemos a crear una configuración y un registro más avanzados.
















Roberto Casas compagina sus estudios de 5º de Ingeniería
Informática en el Centro Politécnico Superior de Zaragoza con su
trabajo en la empresa Master-D y javaHispano.



Para cualquier duda o tirón de orejas, e-mail a:
roberto_ARROBA_javahispano.com




viernes
jun012001

Log4java (Parte 2)

Configurando log4j



En el anterior artículo aprendimos a usar BasicConfigurator, para
utilizar el API log4j de forma sencilla. Esta clase usa un PatternLayout
para mostrar la información que examinaremos a continuación,
para luego aprender a definir nuestros propias instancias de PatternLayout
y conseguir un log personalizado.


El PatternLayout de BasicConfigurator.



BasicConfigurator usa la cadena "%r [%t] %p %c %x -%m%n" como patrón
de conversión para el PatternLayout. Esta cadena se encuentra definida
estáticamente como PatternLayout.TTCC_CONVERSION_PATTERN. Con este
patrón de conversión, PatternLayout ofrece unos resultados
idénticos a los que se obtendrían usando el layout TTCC_Layout.



Ahora vamos a ver paso por paso como se utilizan estos patrones de conversión
(puede encontrar una descripción de todas las opciones que puede incluir
en un patrón de conversión en
http://jakarta.apache.org/log4j/docs/api/org/apache/log4j/PatterLayout.html

).




Las secuencias de carácteres que comienzan con el símbolo
%, son cadenas especiales que se reemplazan por información útil
sobre la aplicación que se está ejecutando.



Con %r mostramos el número de milisegundos desde el comienzo de
la aplicación hasta la petición del registro, en el ejemplo
del artículo anterior corresponde al 0, al 36 y al 51. Para mostrar
el nombre del hilo que generó la petición usamos %t, que como
además se encuentra entre corchetes hará que dicho nombre aparezca
de la misma forma ([main] en el ejemplo del artículo anterior). El
%p se usa para mostrar la prioridad (DEBUG, INFO, ...) del evento de log.
Con %c mostramos la categoría a la que pertenece el evento (en el
ejemplo del artículo anterior corresponde a com.foo.Bar y MyApp).
%x no hace que se muestre nada por pantalla, ya que en la aplicación
no hay contexto de diágnostico anidado (NDC -> nested diagnostic
context) asociado al hilo que generó el evento. Finalmente, con %m
mostramos el mensaje, y con %n se añade el separador de línea
que se use en la plataforma.




Además de los reemplazamientos, podemos utilizar modificadores de
formato al estilo de la familia de funciones printf en C. Para ello vamos
a ver en la siguiente tabla como formatear la cadena con la que se muestra
la categoría a la que pertenece el evento:

















































Modificador de formato

Justificación a izquierda Anchura mínima Anchura máxima Explicación
%20cno20noRellena a la izquierda con espacios si el nombre de la categoría
es menor de 20 carácteres. 
%-20c

20noRellena a la derecha con espacios si el nombre de la categoría
es menor de 20 carácteres.
%.30cN/Dno30Corta desde el principio si el nombre de la categoría
es más largo de 30 carácteres. 
%20.30cfalse2030Rellena a la izquierda con espacios si el nombre de la categoría
es menor de 20 carácteres. De lo contrario, si éste es más
largo de 30 carácteres lo corta desde el principio.    
%-20.30ctrue2030Rellena a la derecha con espacios si el nombre de la categoría
es menor de 20 carácteres. De lo contrario, si éste es más
largo de 30 carácteres lo corta desde el principio.    



Definiendo nuestro propio PatternLayout.



Después de la sección anterior, ya deberíamos de ser
capaces de especificar nuestro propio PatternLayout, y ampliarlo con la información
que podemos encontrar en los documentos del API. Para que sirva como ejemplo,
voy a proponer un PatternLayout que resultará extremadamente útil
en tiempo de depuración, dada la cantidad de información que
proporciona, pero que desaconsejo su uso en versiones finales por problemas
de eficiencia. El PatternLayout que usaremos a continuación será:
"%-5p [%d{ISO8601}] (%M [%C:%L]) - %m%n". Como nueva información,
tendremos la fecha del evento, y el método, la clase y la línea
en la que se produce el evento de log.



Usando PropertyConfigurator con nuestro PatternLayout.



Ahora que hemos aprendido a crear nuestro PatternLayout, debemos saber como
podemos usarlo en nuestras aplicaciones.



Para usar PropertyConfigurator nos crearemos un fichero con las siguientes
líneas:




log4j.rootCategory=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-5p [%d{ISO8601}] (%M [%C:%L]) - %m%n



Con la primera línea especificamos en primer lugar que para la categoría
raíz, sólo se mostrarán los mensajes de prioridad mayor
o igual que DEBUG, y que se usará como Appender (que veremos más
a fondo en el próximo artículo) A1. Se podría añadir
más de un Appender a una categoría separándolos por
comas tras la prioridad. Si quisiéramos definir una prioridad y un
Appender distintos para la categoría com.javahispano podríamos
a continuación añadir:


log4j.category.com.javahispano=INFO, A2


La segunda línea especifica el tipo de Appender, que ya veremos lo
que es. Basta con saber que este hará que toda la información
se nos muestre por pantalla.



La tercera línea hace que el layout del appender que estemos definiendo
sea del tipo PatternLayout.



La última línea es la que asigna el patrón de conversión
que queremos utilizar.



Ya podemos crear una pequeña aplicación para probar nuestro
PatternLayout:




import org.apache.log4j.*;

public class Log4jCap2 {

static Category cat = Category.getInstance(Log4jCap2.class.getName());

public static void main(String[] args) {
PropertyConfigurator.configure(args[0]);
cat.info("Entrando.");
Foo f = new Foo();
f.pru();
cat.info("Saliendo.");
}
}



A continuación vemos la clase Foo que se utiliza en nuestro programa.



import org.apache.log4j.*;

public class Foo {

static Category cat = Category.getInstance(Foo.class.getName());

public Foo() {
cat.debug("Creando un foo");
}

public void pru() {
cat.info("En pru");
}
}


Para ejecutar el programa de prueba simplemente tenemos que pasarle el nombre
que le hayamos dado al fichero de configuración como primer parámetro
y obtendremos:




INFO [2001-05-22 14:01:44,283] (main [Log4jCap2:9]) - Entrando.
DEBUG [2001-05-22 14:01:44,302] (<init> [Foo:7]) - Creando un foo
INFO [2001-05-22 14:01:44,304] (pru [Foo:11]) - En pru
INFO [2001-05-22 14:01:44,306] (main [Log4jCap2:12]) - Saliendo.


Usando DOMConfigurator con nuestro PatternLayout.



Como habrá visto, el esquema del fichero de configuración es
claramente jerárquico, por lo tanto, encaja perfectamente su descripción
dentro de un fichero XML.



Para usar ficheros XML para configurar el log, log4j nos ofrece la clase
DOMConfigurator. Esta clases es muy similar a PropertyConfigurator, pero
espera un fichero en un formato XML determinado por el fichero log4j.dtd (puedes descargar este fichero de aqui).
El fichero de configuración XML equivalente al que hemos usado anteriormente
es el que sigue:



<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="A1" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d{ISO8601}] (%M [%C:%L]) - %m%n"/>
</layout>
</appender>

<root>
<priority value ="debug" />
<appender-ref ref="A1" />
</root>
</log4j:configuration>



La aplicación de prueba quedará en este caso así:



import org.apache.log4j.*;
import org.apache.log4j.xml.*;

public class Log4jCap2 {

static Category cat = Category.getInstance(Log4jCap2.class.getName());

public static void main(String[] args) {
DOMConfigurator.configure(args[0]);
cat.info("Entrando.");
Foo f = new Foo();
f.pru();
cat.info("Saliendo.");
}
}



Y la salida será por supuesto equivalente:



INFO [2001-05-22 14:32:47,328] (main [Log4jCap2:10]) - Entrando.
DEBUG [2001-05-22 14:32:47,363] (<init> [Foo:7]) - Creando un foo
INFO [2001-05-22 14:32:47,365] (pru [Foo:11]) - En pru
INFO [2001-05-22 14:32:47,367] (main [Log4jCap2:13]) - Saliendo.


Próximo artículo.


En el próximo artículo veremos como usar los distintos tipos de Appenders que nos ofrece log4j.
















Roberto Casas compagina sus estudios de 5º de Ingeniería
Informática en el Centro Politécnico Superior de Zaragoza con su
trabajo en la empresa Master-D y javaHispano.



Para cualquier duda o tirón de orejas, e-mail a:
roberto_ARROBA_javahispano.com




viernes
jun012001

Mapeo de XML a Java (Parte 2 - final)


Mapeo de XML a Java (parte 2)


Fecha de creación: 01.06.2001

Revisión 1.0.1 (15.10.2002)

Alberto Molpeceres
al AT javahispano DOT org

Copyright (c) 2002, Alberto Molpeceres. Este documento puede ser distribuido solo bajo los términos y condiciones de la licencia de Documentación de javaHispano v1.0 o posterior (la última versión se encuentra en /licencias/).



Introducción


En este articulo referente al API SAX ampliamos el anterior [1], de forma que tendremos un conocimiento más profundo del interface ContentHandler, básico al trabajar con SAX, y aprenderemos como manipular ficheros XML más complejos que en el ejemplo anterior.


Se espera haber leido y comprendido el artícuo anterior, lo que implica un cierto conocimiento de XML, su estructura y su funcion.



El interface ContentHandler


El interface ContentHandler define los siguientes métodos, que como dijimos se ejecutarán cada vez que ocurra un evento al procesar el documento XML:



public void setDocumentLocator (Locator locator)

Este método recive una instancia de la clase Locator que contendrá la información referente a la posición del docuemtno donde sucede un evento.



public void startDocument () throws SAXException

Simple. El evento que se produce al comenzar a procesar un docuemtno XML.



public void endDocument () throws SAXException

Fin del documento XML



public void processingInstruction (String target, String data)
throws SAXException

Este evento se produce cuando se encuentra una instrucción de proceso de XML (llamadas también PI) distinta al a declaración de decomento XML, como por ejemplo<? Cocoon process type = "xslt" ?>. No entraré a explicar en detalle lo que es una PI, ya que esto no es tutorial de XML, simplemente diré que es una especie de instrucción para ciertos programas que procesas XML. Los argumentos de este método son el destino de la PI y los atributos de dicha instrucción.



public void startPrefixMapping (String prefix, String uri)

Indica el comienzo de un prefijo de un espacio de nombre (Namespace), cuya función también se escapa de los objetivos de este articulo, aunque se puede definir como una forma de identificar inequivocamente los elementos del documento. Los parametros de éste método son el prefijo del espacio de nombres y su dirección URI asociada.



public void endPrefixMapping (String prefix)

Indica cuando se ha terminado la petición de inicio del prefijo del espacio de nombres.



public void startElement (String namespaceURI, String localName,
String rawName, Attributes atts)
throws SAXException

Este método se ejecuta cuando empieza un elemento del documento XML. Los argumentos que recibe son la dirección URI del espacio de nombres asociado al elemento, el nombre del elemento (o etiqueta) sin el prefijo del espacio de nombres, el nombre del elemento en la versión 1.0 de la especificación de XML, y los atributos que contiene la etiqueta en forma de una instancia de la clase Attributes.



public void endElement (String namespaceURI, String localName,
String rawName)

Se produce al teminar un elemento. El sgnificado de los atributos es el mismo que en startElement.



public void characters (char[] ch, int start, int length)
throws SAXException

Este método consigue el valor del elemento, es decir, el contenido entre las etiquetas de inicio y final del elemento. Los parametros que recibe son claros, un array de caracteres, asi como la indicación del inicio y la extension del elemento.



public void ignorableWhitespace (char[] ch, int start, int length)
throws SAXException

Este método indica los espacios en blanco que pueden ser ignorados en el documento, pero normalmente solo se utiliza cuando se valida el documento durante el procesamiento del fichero. Los parametros tienes el mismo significado que en el método anterior, characters.



public void skippedEntity (String name) throws SAXException

Este método indica que una entidad externa se ha ignorado al procesar el fichero (algo que n pasará en un parser estable como es el Xerces). Recibe como parametros el nombre de dicha entidad.


Volviendo a la prática


Y después de toda esta cantidad de palabrería vamos con algo práctico. Como anunciá en el artículo anterior, vamos a ver que hacer cuando en un documento XML existen elementos anidados del estilo de:


Punto de partida



<?xml version="1.0"?>
<clientes>
<empresa>
<nombre> GFT Technologies </nombre>
<direccion> Gran Vía 1 </direccion>
. . .
<persona-contacto>
<nombre> Alberto Molpeceres </nombre>
<cargo> Jefe </cargo>
. . .
</persona-contacto>
</empresa>
</clientes>



Cuando esto ocurre, normalmente es porque son entidades distintas, objetos distintos, por lo tanto clases de java distintas. Una solución sería llenar nuestro ContentHandler de estructuras if y de variables internas que controlasen donde estamos en cada momento, pero eso no sería muy elegante. La solución que aplicaré aqui consistirá en tener varios ContentHandler y pasar el control (y por tanto el proceso del fichero) de uno a otro según se cambie de entidad.


Suponiendo el documento XML anterior, y las siguientes clases:

public class Persona
{
private String nombre;
private String cargo;
. . .
public Persona (){}
. . .
public void setNombre (String nombre)
{
this.nombre = nombre;
}
. . .
public void setCargo (String cargo)
{
this.cargo = cargo;
}
. . .
}

public class Empresa
{
private String nombre;
private String direccion;
. . .
private Persona contacto;
. . .
public Empresa (){}
. . .
public void setNombre (String nombre)
{
this.nombre = nombre;
}
. . .
public void setDireccion (String direccion)
{
this.direccion = direccion;
}
. . .
public void setPersonaContacto (Persona contacto)
{
this.contacto = contacto;
}
. . .
}



Para mapear el fichero tendremos que crear un ContentHandler para cada clase y la lógica de control necesaria para pasar de uno a otro en tiempo de ejecución.


El primer ContentHandler, o principal, pasará el control al segundo al llegar al comienzo de la etiqueta <persona-contacto>, que lo devolverá al primero al llegar a la de fin de entidad </persona-contacto>. Un ejemplo vale más que mil palabras, así que aqui teneis la solución de nuestro problema con los nombres.como soy un poco vago, y ya que no necesitamos todos los métodos, en lugar de implementar el interface ContentHandler extendere el manejador por defecto, DefaultHandler. La idea es la misma, todo depende de lo que necesites.


Handler para empresas


Este es el ContentHandler principal, con el que comienza el proceso, en de las empresas.

import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.Attributes;
import java.util.Vector;

public class EmpresaXMLHandler extends DefaultHandler
{
/* Esto no es nuevo */
//vector de instancias
private Vector instancias;
//"Empresa" que se esta procesando
private Empresa actual;
//valor contenido entre las etiquetas de un elemento
private String valor;

/* Esto si es nuevo */
//Como queremos pasar el control del proceso de un
//Handler a otro, necesitamos tener el parser para
//asignarle el Handler que necesite en cada instante.
private XMLReader parser;
//Este es el Handler que procesara las personas que
//contenga el documento
private PersonaXMLHandler handlerPersona;

public EmpresaXMLHandler (XMLReader parser, Vector v)
{
this.parser = parser;
this.instancias = v;
}

public void startElement( String namespaceURI, String localName, String qName,
Attributes attr ) throws SAXException
{
//comprobamos si empezamos un elemento "pagina"
if (localName.equals("empresa")){
//creamos la nueva instancia de Empresa
actual = new Empresa ();
//y la añadimos al Vector qie las almacena
instancias.addElement (actual);
}
else if (localName.equals("persona-contacto")){
//creamos una instancia de Persona
Persona contacto = new Persona ();
//se la asignamos a la empresa actual como contacto
actual.setPersonaContacto (contacto);
/*
y pasamos el control al Handler de persona contacto
le tenemos que pasar el parser, para que recoga
los datos del fichero, este Handler para que luego
nos devuelva el control, y la persona donde meter
los datos que procese.
*/
handlerPersona = new HandlerPersona( parser, this, contacto );
parser.setContentHandler( handlerPersona );
}
}

public void endElement (String namespaceURI, String localName, String rawName)
throws SAXException
{
/*
miramos de que elemento se trata y asignamos los atributos
correspondientes a la "Empresa" actual.
*/
if (localName.equals("nombre")){
actual.setNombre (valor);
}
else if (localName.equals("direccion")){
actual.setDireccion (valor);
}
valor = null;
}


/*
Los parametros que recibe es la localizacion de los carateres del elemento.
*/
public void characters (char[] ch, int start, int end) throws SAXException
{
//creamos un String con los caracteres del elemento y le quitamos
//los espacios en blanco que pueda tener en los extremos.
valor = new String (ch, start, end);
valor = valor.trim();
}

}



Handler para personas


Ahora el ContentHandler auxiliar que se encargará de procesar la información de las personas de contacto.

import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.Attributes;

public class PersonaXMLHandler extends DefaultHandler
{
//valor contenido entre las etiquetas de un elemento
private String valor;

//El parser, para luego devolver el control al
//Handler de empresas.
private XMLReader parser;
//El Handler al que queremos volver
private EmpresaXMLHandler handlerEmpresa;
//La persona donde meter los datos que leamos.
private Persona persona;

public PersonaXMLHandler (XMLReader parser, EmpresaXMLHandler handler,
Persona persona)
{
this.parser = parser;
this.handlerEmpresa = handler;
this.persona = persona;
}

public void endElement (String namespaceURI, String localName, String rawName)
throws SAXException
{
/*
miramos de que elemento se trata y asignamos los atributos
correspondientes a la "Persona" actual o devolvemos el control
al Handler de empresas.
*/
if (localName.equals("nombre")){
persona.setNombre (valor);
}
else if (localName.equals("cargo")){
actual.setCargo (valor);
}
//si hemos llegado al final de la etiqueta
else if (localName.equals("persona-contacto")){
parser.setContentHandler (handlerEmpresa);
}
valor = null;
}


/*
Los parametros que recibe es la localizacion de los carateres del elemento.
*/
public void characters (char[] ch, int start, int end) throws SAXException
{
//creamos un String con los caracteres del elemento y le quitamos
//los espacios en blanco que pueda tener en los extremos.
valor = new String (ch, start, end);
valor = valor.trim();
}

}



Lanzando el programa


Por ultimo nos queda la clase que empezaría todo, la clase del main. Exactamente igual que la del articulo anterior, así que sobran los comentarios.

import java.util.Vector;

import org.xml.sax.XMLReader;
import org.xml.sax.SAXException;

import org.apache.xerces.parsers.SAXParser;

public class Test
{
Vector instancias = new Vector ();

public Test()
{
}

public void procesarFichero ()
{
try
{
XMLReader parser = new SAXParser();
parser.setContentHandler(new MiXMLHandler(parser, instancias));
parser.parse("misClientes.xml");
}
catch (Exception e)
{
System.out.println ("Error al procesar el fichero de Clientes: "
+ e.getMessage());
e.printStackTrace();
}
}


public static void main(String[] args)
{
Test test = new Test();

test.procesarFichero();
}
}




Conclusión


Pues esto era todo, como veis con dos articulos hemos tenido más que suficiente para mapear los datos de un fichero XML a clases de Java, pero me temo que no todo es así de sencillo, esto solo es una base de iniciación.


Para documentos más complejos ahí teneis todos los métodos del interface ContentHandler, y para manipilaciones más complicadas de XML, donde no llega SAX llega DOM/JDOM. Pero eso es otra historia.



Recursos




[1] ,
/articulos/ver_articulo.jsp?id=2


Acerca del autor

Alberto Molpeceres
Alberto es es ahora mismo desarrollador de aplicaciones en ámbito cliente/servidor para la empresa T-Systems - debis Systemhaus en Munich (Alemania). Cuando no está trabajando o "metiendo caña" al resto de los integrantes de javaHispano intenta pasear con su novia, buscar la desaparecida lógica del idioma alemán o intentar olvidar la pesadilla que es buscar piso en Munich.