java - pom - ¿Hay alguna manera de tratar con definiciones de elementos duplicados en múltiples archivos.xsd en JAXB?
maven-jaxb2-plugin maven (5)
Agregue un elemento <schemaBindings>
a XSD:
<schemaBindings>
<package name="com.whatever.stuff" />
</schemaBindings>
Tengo docenas y docenas de archivos .xsd
que quiero generar códigos automáticamente. Algunos de los archivos tienen nombres duplicados que chocan cuando intento generarlos todos al mismo tiempo.
Me estoy enfocando solo en tratar de hacer que 2 de estos funcionen.
Cuando consiga estos 2 trabajos, arreglaré el resto. Pero solo me estoy enfocando en 2 de estos archivos por ahora. No los controlo, son de un proveedor y siguen un "estándar" , por lo que editarlos no es una opción por varias razones.
Estoy usando el maven-jaxb2-plugin
para procesar estos archivos.
binding.xjb
un archivo binding.xjb
como se sugiere en el enlace en la respuesta de mat b
y otras instrucciones que he encontrado en la web. Pero obtengo los siguientes errores, sin salida.
<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings version="2.1"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xsi:schemaLocation=" http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd">
<jxb:bindings schemaLocation="mac-3.4.xsd">
<jxb:schemaBindings>
<jxb:package name="my.company.mac"/>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings schemaLocation="mac-stylesheet-3.4.xsd">
<jxb:schemaBindings>
<jxb:package name="my.company.stylesheet"/>
</jxb:schemaBindings>
</jxb:bindings>
</jxb:bindings>
da el siguiente error
[ERROR] Error while parsing schema(s).Location [ file:/C:/Users/Jarrod%20Roberson/Projects/spa-tools/spa-lib/src/main/sc
hema/mac-stylesheet-3.4.xsd{165,33}].
org.xml.sax.SAXParseException: ''halign'' is already defined
El elemento ofensivo es: (hay muchos otros, este es solo el primero que choca)
<xsd:simpleType name="halign">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="left" />
<xsd:enumeration value="center" />
<xsd:enumeration value="right" />
</xsd:restriction>
</xsd:simpleType>
Y es idéntico en cada uno de los archivos .xsd
, ¿cómo puedo resolver esta duplicación con solo generar una clase o generar cada una en su propio espacio de nombres de paquete?
Este no es el único elemento duplicado como este, hay muchos, así que simplemente intentar eliminarlos de los archivos tampoco es una opción.
Este halign
está en varios archivos .xsd
y quiero colocarlos en sus paquetes individuales o poder decirle al compilador que use el primero que se generó.
Aquí es donde comencé antes de probar un archivo .xjb
externo, simplemente especificando el package
en el pom.xml
.
¿Cómo configuro el enlace para ignorar las configuraciones duplicadas, asignarlas a paquetes separados o asignarlas a las implementaciones existentes?
Tenga en cuenta que esto es antiguo, pero tuve el mismo error y podría resolverlo al no especificar un paquete de destino , es decir, la opción -b con xjc. Luego, los elementos duplicados se crean en su propio paquete de espacio de nombres y no hay conflicto.
Tengo una solución alternativa a medio camino para esto, pero requiere mucho tiempo. Tuve que crear <execution/>
por separado para cada uno de los archivos que tiene entradas duplicadas.
<executions>
<execution>
<id>jaxb-mac</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<forceRegenerate>true</forceRegenerate>
<generatePackage>my.company.mac</generatePackage>
<schemaDirectory>src/main/schema</schemaDirectory>
<schemaIncludes>
<include>mac-3.4.xsd</include>
</schemaIncludes>
</configuration>
</execution>
<execution>
<id>jaxb-stylesheet</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<forceRegenerate>true</forceRegenerate>
<generatePackage>my.company.stylesheet</generatePackage>
<schemaDirectory>src/main/schema</schemaDirectory>
<schemaIncludes>
<include>mac-stylesheet-3.4.xsd</include>
</schemaIncludes>
</configuration>
</execution>
El <forceRegenerate>true</forceRegenerate>
es importante o solo se ejecutará el primer <execution/>
y el resto pensará que no hay necesidad de ejecutarlo porque estoy generando en el mismo directorio.
Todavía me gustaría una solución menos laboriosa para tratar con los duplicados.
Creo que si hago que el primer .xsd maestro sea un módulo separado que compila en su propio archivo .jar, podría usar la etiqueta <episode/>
y evitar que genere los mismos elementos duplicados una y otra vez, ya que son idénticos en definición.
Desde entonces, he decidido abandonar XML si es posible y JAXB por completo. Hay nuevas y mejores formas de analizar XML y asignarlo a los objetos a partir de esta edición.
Tuvimos un problema similar: teníamos un archivo wsdl y dos archivos xsd en el mismo directorio. El archivo wsdl importa los dos archivos xsd. El problema era que JAXB tomaba en consideración los tres archivos y arrojaba el error ''... ya está definido''. Básicamente se quejaba de que veía el mismo elemento en el archivo wsdl y xsd.
Podríamos solucionar este problema en la configuración del complemento maven (en pom.xml) agregando una etiqueta de exclusión como en el siguiente ejemplo:
<build>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.12.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaLanguage>WSDL</schemaLanguage>
<generatePackage>mywsdl.wsdl</generatePackage>
<args><arg>-XautoNameResolution</arg></args>
<schemas>
<schema>
<fileset>
<excludes>
<exclude>*.xsd</exclude>
</excludes>
</fileset>
</schema>
</schemas>
</configuration>
</plugin>
</plugins>
</build>
Publiqué mi solución para gradle , resuelve problemas duplicados y no requiere archivos xjb:
task generateJaxb() {
ext.sourcesDir = "${buildDir}/generated-sources/jaxb"
ext.classesDir = "${buildDir}/classes/jaxb"
ext.schemaDir = "src/resources/schemas"
ext.tmp = "${buildDir}/tmp/xjc"
doLast() {
project.ant {
taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask",
classpath: configurations.jaxb.asPath
delete(dir: tmp)
mkdir(dir: tmp)
delete(dir: sourcesDir)
delete(dir: classesDir)
mkdir(dir: sourcesDir)
mkdir(dir: classesDir)
}
fileTree(schemaDir){
include ''**/*.xsd''
include ''**/*.wsdl''
}.each{File file->
//println file
project.ant {
taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask",
classpath: configurations.jaxb.asPath
xjc(destdir: tmp, schema:"${file.getAbsolutePath()}") {
arg(value: "-wsdl")
produces(dir: tmp, includes: "**/*.java")
}
copy(todir: sourcesDir) {
fileset(dir: tmp, erroronmissingdir: false) {
include(name: "**/*.java")
}
}
delete(dir: tmp)
mkdir(dir: tmp)
}
}
project.ant {
javac(destdir: classesDir, source: 1.6, target: 1.6, debug: true,
debugLevel: "lines,vars,source",
classpath: configurations.jaxb.asPath) {
src(path: sourcesDir)
include(name: "**/*.java")
include(name: "*.java")
}
copy(todir: classesDir) {
fileset(dir: sourcesDir, erroronmissingdir: false) {
exclude(name: "**/*.java")
}
}
}
}
}
configurations {
jaxb
}
dependencies {
jaxb("com.sun.xml.bind:jaxb-xjc:2.2.4-1")
compile(files(generateJaxb.classesDir).builtBy(generateJaxb))
}
jar {
from generateJaxb.classesDir
}