Java y XML con JAXB2 (III)

05:45PM dic 10, 2007 en categoria Java por Enrique Rodriguez Lasterra

Etiquetas:


En el anterior post veíamos como podíamos realizar configuraciones del compilador XJC en línea y externas para que las clases Java sean tal y como queremos. En este post veremos la configuración de Schema o schemaBinding

Configuración de Schema

Si la configuración global, como su nombre indica, afecta a aspectos generales de la configuración, la configuración de Schema gestiona la relación entre los Schemas de nuestros documentos XML y las clases Java que se generan. Para aplicar estas configuraciones debemos usar la etiqueta <xjb:schemaBindings>. Con ella podemos realizar dos operaciones:

  • Relacionar un Schema con un paquete java especificado por nosotros usando <xjb:package>
  • Que los nombres de nuestras clases Java generadas mantengan un patrón concreto, es decir, que cuenten con un prefijo y/o sufijo definido por nosotros gracias a <jxb:nameXmlTransforms>

Como hemos visto en los ejemplos anteriores, la tarea de ANT XJC, contaba con el parametro package para indicarle al compilador en que paquete queríamos que generase las clases. Este paremetro es incompatible con la configuración <xjb:package> de <xjb:schemaBindings>. De eliminar este parametro de XJC, por defecto todas nuestras clases se crean en un paquete que se corresponde con el namespace de nuestro Schema (http://weblogs.javahispano.org/lasterra/jaxb2 --> org.javahispano.weblogs.lasterra.jaxb2). Respecto a la nomenclatura de las clase Java, todas se llaman igual que los elementos y tipos complejos del Schema. Gracias a la etiqueta <jxb:nameXmlTransforms> podemos añadir un prefijo y/o sufijo a nuestras clases Java.

Ejemplo: Realizar cambios en la configuración para que las clases se generen en el paquete org.lasterra.jaxb2 y que las clases relacionadas con los tipos complejos se creen con el prefijo Type.

Para el modo inline debemos modificar nuestro Schema y añadir como hicimos anteriormente las configuraciones de JAXB2 dentro del bloque <xs:appinfo>.

.....
<xs:appinfo>

<jxb:globalBindings
collectionType="java.util.LinkedList"
generateIsSetMethod="true"
/>
<jxb:schemaBindings>
<jxb:package name="org.lasterra.jaxb2"/>
<jxb:nameXmlTransform>
<jxb:typeName prefix="Type"/>
</jxb:nameXmlTransform>
</jxb:schemaBindings>

</xs:appinfo>
.....

Al ejecutar nuestra tarea de ANT (recordar que es necesario eliminar le atributo package) veremos los cambios en nuestro código, la clase CampoUno se ve afectada por la dos configuraciones y ahora pasa a quedar así:

package org.lasterra.jaxb2;

import ...

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "campo-uno", propOrder = {
"campoUnoUno",
"campoUnoDos"
})
public class TypeCampoUno {

Si cogemos la configuración externa nuestro fichero de binding, añadimos el bloque <jxb:schemaBinding> y ejecutamos la tarea de ANT XJC con el atributo binding apuntando a nuestro fichero xjb, veremos que nos da un error. El mensaje dice:

Compiling file:/D:/proyectos/documentacion/jaxb2/jaxb2-example/schema.xsd
[ERROR] The "jxb:schemaBindings" customization is not associated with any
schema element.

Bien, esta es una de las razones por las que la configuración externa es un poco más complicada que el modo en linea. Un documento XSD puede contar con elementos de varios Schemas.Esta es una de las razones por las que XMLSchema existe frente a los DTDs, por su capacidad de importar elementos de otros schemas y ubicarlos en distintos namespaces de un mismo documento XML.

Al realizar la configuración en linea, realizamos las configuraciones dentro del propio documento, y estas configuraciones se aplican a los elementos que se encuentran bajo la configuración, es decir, el elemento y los subelementos del mismo. Cuando realizamos la configuración externa es necesario indicar esta información. Para ello la etiqueta <jxb:bindings> cuenta con dos atributos:

  • schemaLocation, que indica la ruta al Schema sobre el cual queremos efectuar la configuración. Esta ruta puede ser local (file:/) o de internet (http://).
  • node, con este atributo podemos especificar que parte del documento queremos configurar. El valor consiste en un ruta XPath que selecciona un elemento (y solo uno). No os asustéis, yo tampoco se mucho de XPath, pero en cualquier caso, schemaBinding casi siempre se aplica a todo un schema y por tanto la ruta XPath es en este caso /xs:schema

Dicho esto, para aplicar la configuración de Schema a todo nuestro documento, nuestro fichero xjb quedaría así

<jxb:bindings version="2.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="schema.xsd"
node="/xs:schema">

<jxb:globalBindings
collectionType="java.util.LinkedList"
generateIsSetMethod="true"
/>
<jxb:schemaBindings>
<jxb:package name="org.lasterra.jaxb2"/>
<jxb:nameXmlTransform>
<jxb:typeName prefix="Type"/>
</jxb:nameXmlTransform>
</jxb:schemaBindings>

</jxb:bindings>
</jxb:bindings>

Como podéis ver el resultado es el mismo, y a pesar de la dificultad extra del modo externo, mantenemos el Schema intacto.

Comentarios:

Enviar un comentario:
Los comentarios han sido deshabilitados.