Estás en:

informaciónDESARROLLADO POR:
icono_twiter

Alejandro es socio fundador de Autentia y nuestro experto en J2EE, Linux y optimización de aplicaciones empresariales.

Ingeniero en Informática y Certified ScrumMaster

Si te gusta lo que ves, puedes contratarle para darte ayudate con soporte experto, impartir cursos presenciales en tu empresa o para que realicemos tus proyectos como factoría (Madrid). Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación

Fecha de publicación del tutorial: 2007-08-20
Tutorial visitado 14.211 veces14.211
Descargar el tutorial en PDF


Regístrate para votar
Share |
XMLBeans, una forma de mapear un XML en objetos Java

XMLBeans, una forma de mapear un XML en objetos Java

Creación: 18-08-2007



Índice de contenidos



1. Introducción

Hay varias formas de trabajar con documentos XML. Una de ellas es mapear el XML en objetos Java, de forma que en vez navegar por el XML con un DOM o con XPath, directamente usamos objetos con sus getters y sus setters; lo cual puede resultar muy cómodo para trabajar con un XML dentro de nuestra aplicación.

Dentro de esta técnica podríamos decir que hay dos grandes posibilidades o tecnologías (hay más de dos, pero entre todas podríamos destacar estas por ser las más extendidas y estándar):

  • JAXB (Java Architecture for XML Binding): El es estándar de Java (lo podemos encontrar en el JEE 5). JSR 222 (http://jcp.org/en/jsr/detail?id=222).

  • XMLBeans: Podríamos decir que es el estándar de "facto" por estar altamente extendido. En un principio fue un proyecto de BEA, que posteriormente donaron a la comunidad Apache (http://xmlbeans.apache.org/).

Ambas tecnologías son muy parecidas y hacen prácticamente lo mismo. En este tutorial no voy a entrar en el debate de cual de las dos es mejor. Para eso no tenéis más que buscar en Google "xmlbeans vs jaxb" y encontraréis multitud de referencias.

En este tutorial simplemente vamos a ver una introducción a XMLBeans para ver como podemos obtener, a partir de un DTD, las clases Java que procesan los XML que cumplen ese DTD.

Vamos a hacer un ejemplo práctico donde generaremos las clases Java para procesar los XMLs que genera el Bugzilla como resultado de una búsqueda. Estas clases nos podrán servir para "alimentar" otras aplicaciones con los datos que genera el Bugzilla.

Dejaremos para otro tutorial hacer el mismo ejemplo con JAXB (a ver si alguien se anima y lo hace ;)



2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Asus G1 (Core 2 Duo a 2.1 GHz, 2048 MB RAM, 120 GB HD).

  • Sistema Operativo: GNU / Linux, Debian (unstable), Kernel 2.6.22, KDE 3.5

  • Java 1.5

  • XMLBeans 2.3.0



3. Instalando XMLBeans

Nos descargamos la última release de http://www.apache.org/dyn/closer.cgi/xmlbeans/binaries.

Y la descomprimimos, por ejemplo, en el directorio /opt:

$ cd /opt
$ tar -xzf /directorio_donde_hicimos_la_descarga/xmlbeans-2.3.0.tgz

Si queremos poder ejecutar desde línea de comandos las utilidades que vienen con XMLBeans, sería conveniente poner el directorio /opt/xmlbeans-2.3.0/bin en el PATH del sistema. Por ejemplo, en Debian podemos hacer:

$ export PATH=$PATH:/opt/xmlbeans-2.3.0/bin

A partir de este momento, en la consola donde hemos ejecutado este comando, podremos invocar las utilidades que vienen con XMLBeans sin necesidad de escribir su ruta completa.



4. Generando las clases Java a partir del esquema (XSD)

Sí, has leído bien, XMLBeans sólo es capaz de generar las clases Java a partir de un esquema (un fichero .xsd). Esto puede ser un problema si lo que tenemos es un DTD (como en el ejemplo que hemos planteado).

Aún así no hay que desesperar ;) lo que vamos a hacer es pasar del DTD al XSD y del XSD a las clases Java.



4.1. Pasar del DTD al XSD

El DTD que utiliza Bugzilla lo podéis ver aquí.

En vez de hacer la conversión a mano, lo mejor es usar alguna herramienta que podamos encontrar por Internet. Yo he probado con estas y parece que funcionan correctamente:

  • http://www.hitsw.com/xml_utilites/ - Se trata de una página web donde, de forma gratuita, le indicamos el fichero y nos devuelve el XSD equivalente. Es la opción más cómoda, ya que no tenemos que instalar nada, y lo tendremos resuelto en un momento. Esta es la opción que he seguido yo.

  • http://www.syntext.com/products/index.htm#Dtd2Xs - Se trata de una herramienta tanto para Windows como para Linux. El XSD que genera esta aplicación es prácticamente idéntico a la primera opción que hemos comentado.

El XSD obtenido con la primera opción lo podéis encontrar aquí.

Si os fijáis en el XSD, se declaran todos los elementos como tipos complejos (como en un DTD no se puede especificar el tipo de los elementos, la herramienta a intentado escoger la solución más genérica). Esto no me convence porque es una complejidad innecesaria, así que he editado a mano el fichero generado para cambiar estos tipos complejos por tipos "xs:string" es decir, por cadenas de caracteres (para el ejemplo me va bien, pero podríais especificar el tipo que mejor se ajuste a vuestras necesidades).

El XSD simplificado lo podéis encontrar aquí.



4.2. Pasar del XSD a las clases Java

Para pasar del XSD a las clases Java vamos usar el comando scomp, que viene con XMLBeans. Haremos algo como:

scomp -src src -javasource 1.5 -out bugzilla-3.0-xmltypes.jar bugzilla-3.0-simple.xsd

  • -src src : con esto le estamos diciendo que queremos que nos generé el código fuente (los .java) en el directorio src. Esta opción no es obligatoria, es sólo por si luego tenéis curiosidad de ver el código que genera XMLBeans. Si no ponemos está opción se limitará a generar un .jar con las clases que necesitamos.

  • -javasource 1.5 : con esta opción le estamos indicando que tipo de código Java queremos que genere. Podemos elegir entre 1.4 o 1.5.

  • -out bugzilla-3.0-xmltypes.jar : estamos indicando el nombre del jar (por defecto xmltypes.jar) que se va a crear con las clases generadas y compiladas.

  • bugzilla-3.0-simple.xsd : el nombre del fichero XSD que queremos usar para generar las clases Java.

Si todo funciona correctamente deberíamos ver en la consola algo como:

Time to build schema type system: 0.782 seconds
Time to generate code: 0.811 seconds
Time to compile code: 6.144 seconds
Compiled types to: bugzilla-3.0-xmltypes.jar

Y deberíamos tener el jar bugzilla-3.0-xmltypes.jar con todas las clases necesarias para procesas los XMLs generados por el Bugzilla.



4.3. Definiendo el paquete para las clases generadas

Si nos fijamos en las clases generadas (no hay más que entrar en el directorio src), veremos que las ha puesto en el paquete noNamespace. Esto no es nada conveniente, y nunca debemos generar clases en el paquete noNamespace; ya que si en un mismo proyecto tenemos mas clases generadas con XMLBeans, pertenecientes a XMLs diferentes, todas estarían dentro del mismo paquete y podrían entrar en conflicto.

El hecho de que el paquete utilizado sea noNamespaces, se debe a que nuestro esquema no tenía definido el targetNamespace. Por ejemplo, si nuestro XSD hubiera tenido el siguiente tergetNamespace:

<xs:schema targetNamespace="http://autentia.com/xmlbeans/bugzilla"
        xmlns:cr="http://autentia.com/xmlbeans/bugzilla"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
    ...

las clases se hubieran generado en el paquete:

com.autentia.xmlbeans.bugzilla

Otra forma de especificar el paquete para las clases Java, bien si no tenemos definido el targetNamespace o bien porque queremos generarlas en otro paquete, sería usando un fichero para configurar como se debe hacer la generación de código. Este fichero debe tener la extensión .xsdconfig.

En nuestro caso, por ejemplo, si no quisiéramos añadir el targetNamespace a nuestro XSD, podríamos usar el siguiente fichero de configuración (bugzilla-3.0.xsdconfig):

<?xml version="1.0" encoding="UTF-8"?>
<xb:config xmlns:xb="http://xml.apache.org/xmlbeans/2004/02/xbean/config">
    <xb:namespace uri="##any">
        <xb:package>com.autentia.xmlbeans.generated.bugzilla30</xb:package>
    </xb:namespace>
</xb:config>

Nótese como en el atributo uri del elemento xb:namespace, se ha puesto el valor ##any. Este indica que, en ausencia de targetNamespace, se debe usar el paquete indicado en el elemento xb:package.

Si en vez de ##any hubiéramos especificado un namespace, lo que estaríamos haciendo es cambiar un nombre de paquete por otro.

Para más información sobre este fichero de configuración se puede consultar: http://dev2dev.bea.com/lpt/a/8

Para lanzar la generación usando el fichero de configuración, lo añadiremos como último parámetro del comando scomp. Por ejemplo:

scomp -src src -javasource 1.5 -out bugzilla-3.0-xmltypes.jar bugzilla-3.0-simple.xsd bugzilla-3.0.xsdconfig



5. Ejemplo de uso de las clases generadas

Ahora que ya tenemos el jar con las clases generadas, ya podemos usarlo en nuestros proyectos.

Para leer uno de estos XMLs generados por el Bugzilla haríamos algo como:

...

// Leemos el XML y lo convertimos en objetos
BugzillaDocument doc = BugzillaDocument.Factory.parse(new File(file));

// Ahora podemos trabajar con los objetos
final List<Bug> bugs = doc.getBugzilla().getBugList();

...

Como se puede ver, es muy sencillo, ya que basta con ir llamando a los métodos de las clases generadas por XMLBeans.



6. Conclusiones

Gracias a XMLBeans hemos visto como en pocos minutos podemos generar un jar que nos permite operar con XMLs que sigan un determinado esquema, tanto para leerlos, como para escribirlos, ...

El conocimiento de la existencia de este tipo de herramientas nos puede ahorrar mucho tiempo y quebraderos de cabeza.



7. Sobre el autor

Alejandro Pérez García, Ingeniero en Informática (especialidad de Ingeniería del Software)

Socio fundador de Autentia (Formación, Consultoría, Desarrollo de sistemas transaccionales)

mailto:alejandropg@autentia.com

Autentia Real Business Solutions S.L. - "Soporte a Desarrollo"

http://www.autentia.com



Anímate y coméntanos lo que pienses sobre este TUTORIAL:

Puedes opinar o comentar cualquier sugerencia que quieras comunicarnos sobre este tutorial; con tu ayuda, podemos ofrecerte un mejor servicio.


(Sólo para usuarios registrados)

» Registrate y accede a esta y otras ventajas «

Comentarios