当前位置: 首页 > 面试题库 >

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

卫骏
2023-03-14
问题内容

我有一个项目,该项目的架构A和架构B都在同一个名称空间中。两者都导入模式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>

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

target/generated-sources/xjc-commons/META-INF/sun-jaxb.episode

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


问题答案:

免责声明: 我是maven-jaxb2-plugin的作者。

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>

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

好的,这将创建具有三个目标软件包的三个目标目录。下一个问题是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>

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

                <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.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>

这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>


 类似资料:
  • 问题内容: 我想将多个xsd模式解组到 同一 文件夹下的不同程序包中。我尝试了两个插件,并且似乎都可以在这两种配置下正常工作,但是在使用maven- jaxb2-plugin的情况下,eclipse插件会无限期地生成类(由于= true),但是如果我不指定forceRegenerate,它将不会生成运行时完全没有第二组和第三组类,我的配置是否有问题? jaxb2-maven-插件 maven-ja

  • 我有多个xsd模式,我想将它们解组到同一文件夹下的不同包中。我尝试了这两个插件,两个插件似乎都能很好地处理这两种配置,但在maven-jaxb2-plugin的情况下,eclipse插件会无限期地生成类(因为=true),但是如果我没有指定forceRegenate,当我运行我的配置有任何问题吗? jaxb2 maven插件 maven-jaxb2-plugin 以及build helper ma

  • 我使用Maven3.3.3和maven-jaxb2-plugin Version0.12.1从XSD模式生成java类。XSD所在的地址返回HTTP 302,插件抛出: 是否可以指定xjc编译器遵循302到正确的链接,或者不去尝试下载XSD?

  • 问题内容: 有什么方法可以在Maven中的父项目的模块之间共享资源?例如,我想为一个多模块Maven项目中的所有模块指定一个log4j.properties文件。 通常,我使用Eclipse IDE通过选择常规项目来创建父项目,然后通过指定的包装将其转换为Maven项目。这将创建一个没有and等文件夹的“干净”项目结构。我不知道在这种情况下应该在哪里放置这样的共享资源。 EDIT1 :我想将公共资

  • 我正在使用maven-jaxb2-plugin生成JAXB类。我无法控制WSDL或XSD。 XSD指定了一个单一的“MyObject”,或者一个包含“MyObject”列表的父对象。我知道它们是一样的。但是插件没有(自然地)。有没有办法让它对两者都使用一个(非内部)类?否则,我需要写很多重复的代码... 谢谢

  • 我对Jaxb和这个maven-jaxb2插件非常陌生 这是我的. xsd文件: 这是我的。xjb文件: 当它生成时,它给出的java类有点像: 但是我不想为用户和用户列表重复相同的代码,我可以通过注释或定义正则表达式来做什么。请建议一些方法。 我只是想知道这段代码要写什么 因此,当它创建用户类时,它会显示@xmlRootElement(name='user'),而其他类的@xmlRootEleme