Java y XML con JAXB2 (III)
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.
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.
- 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.





