Отказ от ответственности: Я являюсь автором maven-jaxb2-plugin .
TL; DR вот тестовый проект , который демонстрирует, как это сделать.
Это возможно, но немного волосато, поэтому, пожалуйста, потерпите меня.
Если a.xsd
, b.xsd
и c.xsd
находятся в одном и том же пространстве имен, a.xsd
и b.xsd
не могут импортировать c.xsd
, они могут только включать Это. Мы хотим сгенерировать каждый из XSD в свой собственный пакет, скажем, test.a
, test.b
и test.c
и сделать это в одном и том же проекте Maven.
Для этого нам понадобятся три отдельных исполнения maven-jaxb2-plugin
, каждое из которых настроено на собственную схему и целевой пакет. Например:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<id>xjc-a</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generatePackage>test.a</generatePackage>
<generateDirectory>${project.build.directory}/xjc-a</generateDirectory>
<schemaIncludes>
<includes>a.xsd</includes>
</schemaIncludes>
</configuration>
</execution>
<!-- xjc-b and xjc-c follow -->
</executions>
</plugin>
Важно использовать разные целевые каталоги для отдельных исполнений .
ОК, это создаст три целевых каталога с тремя целевыми пакетами. Следующая проблема заключается в том, что классы из c.xsd
будут сгенерированы в test.a
и test.b
, которых мы хотим избежать.
Чтобы добиться этого, мы должны указать XJC использовать классы из test.c
для типов из c.xsd
. Это на самом деле то, для чего эпизод файл. Этот файл обычно создается в META-INF\sun-jaxb.episode
и содержит привязки для всех типов в обработанной схеме. Вот пример, сгенерированный для c.xsd
:
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" if-exists="true" version="2.1">
<bindings xmlns:tns="urn:test" if-exists="true" scd="x-schema::tns">
<schemaBindings map="false">
<package name="test.c"/>
</schemaBindings>
<bindings if-exists="true" scd="~tns:CType">
<class ref="test.c.CType"/>
</bindings>
</bindings>
</bindings>
Файл эпизода на самом деле обычный файл привязок. Так что вы можете напрямую использовать его в компиляции:
<execution>
<id>xjc-a</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generatePackage>test.a</generatePackage>
<generateDirectory>${project.build.directory}/xjc-a</generateDirectory>
<schemaIncludes>
<includes>a.xsd</includes>
</schemaIncludes>
<bindings>
<binding>
<fileset>
<directory>${project.build.directory}/xjc-c/META-INF</directory>
<includes>
<include>sun-jaxb.episode</include>
</includes>
</fileset>
</binding>
</bindings>
</configuration>
</execution>
Осталась только одна крошечная проблема. Файлы эпизодов, сгенерированные XJC, также содержат этот фрагмент:
<schemaBindings map="false">
<!-- ... -->
</schemaBindings>
Он фактически говорит: "не генерируйте код для схемы в заданном пространстве имен". Это не будет проблемой, если a.xsd
или b.xsd
будут в другом пространстве имен. Но поскольку они находятся в одном и том же пространстве имен, этот фрагмент фактически отключит генерацию кода для a.xsd
или b.xsd
.
.
Чтобы обойти это, мы можем постобработать sun-jaxb.episode
, который был сгенерирован для c.xsd
. Это можно сделать с помощью простого XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="jaxb:schemaBindings"/>
</xsl:stylesheet>
Этот XSLT следует запускать после кода для c.xsd
, но до генерации кода для a.xsd
и b.xsd
. Этого можно достичь, поместив эти исполнения в разные фазы (generate-sources
, process-sources
, generate-resources
).
Ниже приведено полное pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>divide</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.2.11</version>
</dependency>
<!-- JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0.2</version>
<executions>
<execution>
<goals>
<goal>transform</goal>
</goals>
<phase>process-sources</phase>
</execution>
</executions>
<configuration>
<transformationSets>
<transformationSet>
<dir>${project.build.directory}/xjc-c/META-INF</dir>
<outputDir>${project.build.directory}/xjc-c/META-INF</outputDir>
<includes>
<include>sun-jaxb.episode</include>
</includes>
<stylesheet>src/main/xslt/removeJaxbSchemaBindings.xslt</stylesheet>
</transformationSet>
</transformationSets>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.13.3</version>
<executions>
<execution>
<id>xjc-c</id>
<goals>
<goal>generate</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<generatePackage>test.c</generatePackage>
<generateDirectory>${project.build.directory}/xjc-c</generateDirectory>
<schemaIncludes>
<includes>c.xsd</includes>
</schemaIncludes>
</configuration>
</execution>
<execution>
<id>xjc-a</id>
<goals>
<goal>generate</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<generatePackage>test.a</generatePackage>
<generateDirectory>${project.build.directory}/xjc-a</generateDirectory>
<schemaIncludes>
<includes>a.xsd</includes>
</schemaIncludes>
<bindings>
<binding>
<fileset>
<directory>${project.build.directory}/xjc-c/META-INF</directory>
<includes>
<include>sun-jaxb.episode</include>
</includes>
</fileset>
</binding>
</bindings>
</configuration>
</execution>
<execution>
<id>xjc-b</id>
<goals>
<goal>generate</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<generatePackage>test.b</generatePackage>
<generateDirectory>${project.build.directory}/xjc-b</generateDirectory>
<schemaIncludes>
<includes>b.xsd</includes>
</schemaIncludes>
<bindings>
<binding>
<fileset>
<directory>${project.build.directory}/xjc-c/META-INF</directory>
<includes>
<include>sun-jaxb.episode</include>
</includes>
</fileset>
</binding>
</bindings>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>