Maven-jaxb2-plugin在同一项目中重用公共XSD

Ben*_*ema 4 java jaxb xjc maven maven-jaxb2-plugin

我有一个项目,在同一名称空间中都有一个架构A和B。两者都导入模式C,该模式C也使用相同的名称空间。如何重用A和B的JAXB类来分离包,同时将C生成的JAXB类重用到公共包?

我已经知道我可能应该使用情节,并将为模式C生成的情节用作绑定文件,以分别执行模式A和B。问题是我不知道如何引用此生成的情节文件。

这是一个例子:

<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.12.3</version>
    <executions>
        <execution>
            <id>generate-sources-C</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <generatePackage>com.mymodel.commons</generatePackage>
                <generateDirectory>${project.build.directory}/generated-sources/xjc-commons</generateDirectory>
                <schemas>
                    <schema><url>src/main/resources/xsd/mymodel/c.xsd</url></schema>
                </schemas>
            </configuration>
        </execution>
        <execution>
            <id>generate-sources-A</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <generatePackage>com.mymodel.a</generatePackage>
                <schemas>
                    <schema><url>src/main/resources/xsd/mymodel/a.xsd</url></schema>
                </schemas>
            </configuration>
        </execution>
        <execution>
            <id>generate-sources-B</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <generatePackage>com.mymodel.b</generatePackage>
                <schemas>
                    <schema><url>src/main/resources/xsd/mymodel/b.xsd</url></schema>
                </schemas>
            </configuration>
        </execution>
    </executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)

这将导致在以下情况下创建情节文件:

target/generated-sources/xjc-commons/META-INF/sun-jaxb.episode
Run Code Online (Sandbox Code Playgroud)

我如何在A和B的执行中引用此情节/绑定文件?使用情节仅提及如何从其他jar依赖项引用情节文件(或者我只是不太正确地理解它,这很有可能)。

我看到一个较旧的答案建议将其作为参数传递-b给XJC,但这似乎对我没有任何帮助。我仍然最终从C生成了三次相同的类。

lex*_*ore 5

免责声明:我是

TL; DR这是一个测试项目,演示了如何执行此操作。

这是可能的,但是有点毛,所以请多多包涵。

如果a.xsdb.xsdc.xsd在同一个命名空间,a.xsd并且b.xsd不能导入 c.xsd,也只能包括它。我们希望将每个XSD生成到自己的包中,例如test.atest.btest.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>
Run Code Online (Sandbox Code Playgroud)

对不同的执行使用不同的目标目录很重要

好的,这将创建具有三个目标软件包的三个目标目录。下一个问题是from c.xsd中将生成类,test.a并且test.b我们希望避免此类。

为此,我们必须告诉XJC对from test.c的类型使用from 类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>
Run Code Online (Sandbox Code Playgroud)

情节文件实际上是一个普通的绑定文件。因此,您可以在编译中直接使用它:

                <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>
Run Code Online (Sandbox Code Playgroud)

剩下的只有一个小问题。XJC生成的情节文件也包含以下片段:

    <schemaBindings map="false">
      <!-- ... -->
    </schemaBindings>
Run Code Online (Sandbox Code Playgroud)

它有效地说,“别产生在给定的命名空间的架构代码”。如果a.xsdb.xsd位于其他名称空间中,这将不是问题。但是,由于它们位于同一名称空间中,因此该片段将有效地关闭a.xsdor的所有代码生成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>
Run Code Online (Sandbox Code Playgroud)

这XSLT应的代码后运行c.xsd,但之前的代码a.xsdb.xsd生成。这可以通过将这些执行几个不同的阶段来实现(generate-sourcesprocess-sourcesgenerate-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>
Run Code Online (Sandbox Code Playgroud)