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

APIs de Java para XML


El API JAXB

JAXB proporciona un forma rápida y conveniente de crear un mapeo de dos vías entre documentos XML y objetos Java. Dando un DTD, el compilador JAXB genera un conjunto de clases Java, que contienen todo el código para analizar documentos XML basados en ese esquema. Un desarrollador usando las clases generadas puede construir un árbol de objetos Java representando un documento XML, manipular el contenido del árbol, y regenerar el documento XML desde el árbol.

Para empezar a usar una aplicación JAXB todo lo que necesitamos es un esquema, que en la versión de JAXB actual, debe ser un DTD. Podemos escribir nuestro propio DTD, u obtenerlo desde cualquier otro lugar, como un repositorio de DTDs estándars al que se accede a través de JAXR.

Una vez que tenemos nuestro DTD, lo unimos a un conjunto de clases realizando los siguientes pasos:

  1. Escribir un esquema de unión, que contiene las instrucciones para unir el esquema a las clases. El esquema de unión está escrito en un lenguaje de unión basado en XML, que está incluido con el JAXB.
  2. Ejecutar el compilador de esquema, que toma un DTD y un esquema de unión y genera las clases a partir de ellos. Cada clase que genere el compilador tiene un método get y otro método set. Cuando se crea e inicializa con datos un ejemplar de la clase, podemos usar estos métodos accesores para acceder a los métodos. Un conjunto de métodos accesores se llama una propiedad.

. Generar Clases desde un DTD

Como ejemplo de generación de clases desde un DTD, consideremos el siguiente DTD, que se llama "priceList.dtd".

<!ELEMENT priceList (coffee)+ >
<!ELEMENT coffee (name, price) >
<!ELEMENT name (#PCDATA) >
<!ELEMENT price (#PCDATA) >

El compilador de esquema JAXB es suficientemente poderoso como para hacer asumciones razonables desde el DTD y el esquema de unión que especifica sólo el elemento raíz del documento. Todo lo que necesitamos especificar en el esquema de unión es que el elemento price es convertido a una propiedad que devuelve y acepta un BigDecimal:

...
<element name="priceList" type="class" class="PriceList" root="true" />
<element name="price" type="value" convert="BigDecimal" />
<conversion name="BigDecimal" type="java.math.BigDecimal" />
...

Desde este DTD y este esquema de unión, el compilador de esquema genera una clase PriceList y una clase Coffee.

La clase PriceList incluye un constructor y una lista de propiedades, a las que está unida el elemento coffee. La clase Coffee contiene un constructor y una propiedad para representar el nombre del café y una propiedad para representar el precio. Los métodos accesores para el precio son:

BigDecimal getPrice();
void setPrice(BigDecimal x);

Las dos clases también contienen métodos para desempaquetar, validar y empaquetar. Desempaquetar es el proceso de construir una represención objeto del dato XML. La validación es el proceso de chequear si el objeto está conforme a las especificaciones del DTD. Empaquetar es el proceso de generar datos XML desde una representación objeto.

. Construir Representaciones Objeto de Datos XML

Después de generar nuestras clases, podemos escribir aplicaciones Java que las usen para construir representaciones objeto del documento XML que sean válidos con respecto al DTD. Cada objeto corresponde a un elemento del documento XML. De forma similar, cada objeto es un ejemplar de una clase del conjunto de clases generadas. Como los objetos se mapean tanto al documento como a las clases, tenemos dos formas diferentes de construir el árbol de objetos Java: desempaquetando un documento XML válido, o ejemplarizando objetos desde las clases. De esta forma, JAXB nos permite procesar documentos XML existentes y crer nuevos datos XML ejemplarizando las clases generadas.

Supongamos que tenemos este documento XML:

<priceList>
    <coffee>
        <name>Arabica</name>
        <price>13.50</price>
    </coffee>
    <coffee>
        <name>Mocha Java</name>
        <price>11.95</price>
    </coffee>
    <coffee>
        <name>Sumatra</name>
        <price>12.50</price>
    </coffee>
</priceList>

Para desempaquetar este documento XML, creamos un stream de entrada desde él y llamamos al método unmarshal de la clase PriceList:

FileInputStream fis = new FileInputStream("priceList.xml");
PriceList myPrices = PriceList.unmarshal(fis);

Ahora tenemos un árbol de objetos Java con el objeto myPrices como la raíz del árbol.

Supongamos que queremos crear nuestra propia lista de precios de cafés como un documento XML. Primero cramos el árbol de objetos por ejemplarización y luego empaquetamos el árbol en un documento XML. Para crear un árbol de objetos usando ejemplarización, creamos un objeto PriceList, obtenemos la lista de objetos Coffee desde él, creamos un nuevo objeto Coffee, y lo añadimos a la lista:

PriceList myNewPrices = new PriceList();
List listOfCoffees = myNewPrices.getCoffees();
Coffee zCoffee = new Coffee();
zCoffee.setName("Zapoteca");
zCoffee.setPrice("15.00");
listOfCoffees.add(zCoffee);

Una vez que tenemos el dato XML en forma de un árbol de objetos, podemos trabajar con los datos como con cualquier otro objeto Java. De esta forma, JAXB proporciona un interface de programación Java para XML y nos permite la integración de datos XML dentro de apliaciones Java.

. Acceder a Datos desde el Árbol de Objetos

Supongamos que queremos cambiar el precio de "Mocha Java" en el primer árbol de objetos que creamos. Todo lo que hacemos es encontrar "Mocha Java" en la lista de cafés y seleccionar un nuevo precio llmando al método setPrice sobre el objeto Coffee:

List coffees = myPrices.getCoffees();
for (ListIterator i = coffees.listIterator(); i.hasNext(); ) {
    Coffee myCoffee = (Coffee) i.next();
    if (myCoffee.getName().equals("Mocha Java") ) {
        myCoffee.setPrice("12.50");
    }
}

. Escribir Documentos XML desde el Árbol de Objetos

Siempre que usemos desempaquetamiento o ejemplarización para construir nuestra representación objeto, podemos empaquetar los objetos en un documento XML, lo que significa que JAXB también permite crear nuevos documentos XML que son válidos con respecto al esquema.

Para empaquetar nuestro árbol de objetos modificados en un nuevo documento XML, creamos un fichero XML y un stream de salida para llamar al método marshal sobre el objeto myNewPrices:

File newPrices = new File("newPriceList.xml");
FileOutputStream fos = new FileOutputStream(newPrices);
myNewPrices.marshal(fos);

. Sumario

JAXB esencialmente proporciona un puente entre XML y la tecnología Java. Al igual que un documento XML es un ejemplar de un esquema, un objeto Java es un ejemplar de una clase. Así, JAXB nos permite crear objetos Java al mismo nivel conceptual que los datos XML. Representar nuestros datos de esta forma nos permite manipularlos de la misma forma que manipularíamos objetos Java, haciendo fácil el crear aplicaciones para procesar datos XML. Una vez que tenemos nuestros datos en forma de objetos Java, es fácil acceder a ellos. Además, después de trabajar con los datos, podemos escribir los objetos Java en un nuevo, y válido documento XML. Con el sencillo acceso a datos XML que proporciona JAXB, somos libres para escribir aplicaciones que realmente usen los datos, en lugar de gastar tiempo en escribir código para analizar y procesar los datos.

. Diferencias entre JAXP y JAXB

JAXP y JAXB sirven a muy diferentes propósitos. La arquitectura o el API que elijamos depende de los requerimientos de nuestra aplicación. Una ventaja de JAXP es que nos permite analizar y procesar los datos desde el mismo conjunto de APIs. Si sólo queremos grabar unos pocos datos de un gran documento, deberíamos usar un analizador SAX porque analiza los datos como un stream, l o que es muy rápido. Si tenemos un documento que no es muy largo, y queremos añadirle o eliminarle datos, deberíamos usar DOM. Aunque un árbol DOM puede ocupar una gran cantidad de memoria, el API DOM incluye funciones comunes para manipulación de árboles. Si queremos transformar los datos a otro formato, deberíamos usar JAXP, que incluye el API transformer y una transformación XSLT en la implementación de referencia que nos permite transformar documentos XML, eventos SAX o árboles DOM. JAXP también nos pemite la flexibilidad de validar los datos o no.

Si queremos construir una representación objeto de datos XML, pero necesitamos evitar las limitaciones de memoria de DOM, deberíamos usar JAXB. Las clases creadas con JAXB no incluyen capacidades de manipulación de árboles, que es un factor que contribuye al pequeño uso de memoria de un árbol de objetos JAXB. Otra ventaja de este tipo de árboles es que podemos añadir árboles además de que los objetos hijos pueden tener más de un objeto padre. Además, procesar los datos con JAXB es casi tan rápido como procesarlos con un analizador SAX porque las clases generadas contienen toda la lógica del DTD, por lo tanto evitan la interpretación dinámica que el analizador SAX debe realizar. El hecho de que JAXB requiera un DTD no lo hace menos flexible que JAXP, sino que además este requerimiento garantiza que sólo se procesarán los datos que sean válidos. Esta garantía es muy importante, especialmente si una aplicación recibe datos desde otra fuente. Si una aplicación no tiene un DTD, no puede determinar el significado de los datos y cómo deberian ser procesados. Otra ventaja que JAXB tiene sobre JAXP es que nos permite especificar cómo se genera neustro código desde nuestro DTD, incluyendo los tipos de datos que un elemento de unión acepta y devuelve.

Claramenete, JAXP y JAXB tienen sus propias ventajas y desventajas, que nosotros necesitaremos considerar cuando elijamos el API para procesar datos XML. Estas dos listas sumarizan las ventajas de JAXB y JAXP para que podamos decidir cuál es el correcto para nuestra aplicacion:

Usaremos JAXB cuando queramos:

  • Acceder a datos en memoria, pero no necesitemos capacidades de manipulación.
  • Procesar sólo datos que son válidos.
  • Convertir datos a diferentes tipos.
  • Generar clases basadas en un DTD.
  • Construir representaciones Objetos de datos XML.

Usaremos JAXP cuando queramos:

  • Tener flexibilidad en la forma de acceder a nuestros datos: serialmente con SAX o aleatoriamente en memoria con DOM.
  • Usar el mismo código de proceso con documentos basados en diferentes DTDs.
  • Analizar documentos que no sean necesariamente válidos.
  • Aplicar transformaciones XSLT.
  • Insertar o eliminar objetos desde un árbol de objetos que representa datos XML.
 
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