Есть ли способ справиться с повторяющимися определениями элементов в нескольких файлах .xsd в JAXB?
У меня есть десятки и десятки файлов .xsd
, для которых я хочу автогенерировать код. Несколько файлов имеют повторяющиеся имена, которые сталкиваются, когда я пытаюсь сгенерировать их все в одно и то же время.
Я сосредотачиваюсь только на том, чтобы попытаться заставить 2 из них работать.
Когда я получу эти 2 работы, я исправлю остальные. Но сейчас я сосредоточен на двух этих файлах. Я не контролирую их, они от поставщика и следуют "стандарту", поэтому редактирование их не является вариантом по нескольким причинам.
Я использую maven-jaxb2-plugin
для обработки этих файлов.
Я добавил файл binding.xjb
, как указано в ссылке в ответе mat b
и других инструкциях, которые я нашел в Интернете. Но я получаю следующие ошибки: нет вывода.
<?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>
дает следующую ошибку:
[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
Оскорбительный элемент: (есть много других, это только первый, который сталкивается)
<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>
И одинаково в каждом из файлов .xsd
, как мне разрешить это дублирование с генерированием только одного класса или каждого из них, сгенерированных в их собственное пространство имен пакетов?
Это не единственный повторяющийся элемент, как это, их много, поэтому просто попытка удалить их из файлов также не является вариантом.
Этот halign
находится в нескольких файлах .xsd
, и я хочу либо поместить их в свои отдельные пакеты, либо дать возможность компилятору использовать первый, который был сгенерирован.
Вот где я начал, прежде чем я попробовал внешний файл .xjb
, просто указав package
в pom.xml
.
Как настроить привязку, чтобы игнорировать дубликаты конфигураций, сопоставлять их для разделения пакетов или сопоставления их с существующими реализациями?
Ответы
Ответ 1
У меня есть решение на полпути с обходным решением, но оно очень интенсивно.
Мне нужно было создать отдельный <execution/>
для каждого из файлов с дублирующимися записями.
<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>
<forceRegenerate>true</forceRegenerate>
важен, или только первый <execution/>
будет запущен, а остальные будут думать, что нет необходимости запускать, потому что я генерирую в тот же каталог.
Мне все равно хотелось бы менее трудоемкое решение для работы с дубликатами.
Я думаю, что если я сделаю первый мастер .xsd отдельным модулем, который будет встроен в свой собственный .jar файл, я мог бы использовать тег <episode/>
и пропустить его повторное создание одинаковых повторяющихся элементов снова, так как они идентичны в определении.
С тех пор я решил отказаться от XML, если это вообще возможно, и JAXB полностью. Есть более новые и более эффективные способы анализа XML и сопоставление его с объектами как с этим редактированием.
Ответ 2
Реализуем, что это старое, но у меня была такая же ошибка, и я могу решить ее с помощью не указывая целевой пакет, то есть параметр -b с помощью xjc. Затем каждый дубликат элементов создается в своем собственном пакете пространства имен и не конфликтует.
Ответ 3
Добавьте элемент <schemaBindings>
в XSD:
<schemaBindings>
<package name="com.whatever.stuff" />
</schemaBindings>
Источник
Ответ 4
У нас была аналогичная проблема: у нас был один файл wsdl и два xsd файла в одном каталоге. Файл wsdl импортирует два файла xsd. Проблема заключалась в том, что JAXB учитывал все три файла и выбрасывал ошибку "... уже определен". В основном он жаловался, что видел один и тот же элемент в файле wsdl и xsd.
Мы могли бы исправить эту проблему в конфигурации maven plugin (в pom.xml), добавив тег exclude, как показано в следующем примере:
<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>
Ответ 5
Я отправляю свое решение для gradle, он решает дублирующую проблему и не требует файлов 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
}