【问题标题】:How can I generate classes from outside XSD file using JAXB XJC如何使用 JAXB XJC 从外部 XSD 文件生成类
【发布时间】:2014-10-10 09:54:30
【问题描述】:

我有两个项目:

一个 /src/main/resources/schema.xsd pom.xml

B /src/main/gen pom.xml

我想在 B 项目中从 XSD 生成类,这些类存在于 A 项目中

在 B 项目的 pom.xml 中我有:

<dependencies>
    <dependency>
        <groupId>test</groupId>
        <artifactId>A</artifactId>
        <version>${project.version}</version>
    </dependency>
</dependencies>
<build>
    <plugins>
       <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>jaxb2-maven-plugin</artifactId>
        <executions>
            <execution>
                <id>xjc</id>
                <goals>
                    <goal>xjc</goal>
                </goals>
            </execution>
            </executions>
            <configuration>
                <schemaDirectory>src/main/resources</schemaDirectory>
                <outputDirectory>src/main/gen</outputDirectory>
            </configuration>
        </plugin>
    </plugins>

</build>

但是在类路径中找不到 xsd 文件:

未能在项目 B 上执行目标 org.codehaus.mojo:jaxb2-maven-plugin:1.5:xjc (xjc):未找到架构

如何使用另一个项目的 xsd?

【问题讨论】:

    标签: java jaxb xsd xjc


    【解决方案1】:

    我的maven-jaxb2-plugin 支持separate schema compilation

    如何做到这一点:

    • 将您的工件 a 添加为剧集。
    • 如果将a.xsd 导入b.xsd,则在编译b 时必须使此架构可用于JAXB:
      • 一种方法是使用 Maven 依赖插件从工件 a 中提取 a.xsd
      • 另一种方法是使用目录文件将a.xsd 的位置重写为工件a

    例如见this test project

    a 项目完全不引人注目。只需编译架构a.xsd

    项目b 更有趣。一起来看看吧。

    pom.xml:

            <plugin>
                <groupId>org.jvnet.jaxb2.maven2</groupId>
                <artifactId>maven-jaxb2-plugin</artifactId>
                <configuration>
                    <catalog>src/main/resources/catalog.cat</catalog>
                    <episodes>
                        <episode>
                            <groupId>org.jvnet.jaxb2.maven2</groupId>
                            <artifactId>maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a</artifactId>
                        </episode>
                    </episodes>
                </configuration>
            </plugin>
    

    配置说使用工件a 作为剧集。所以当 JAXB/XJC 遇到 a 中编译的类时,它会重用它们而不是生成新的。

    顺便说一句,您可以使用useDependenciesAsEpisodes 而不是配置单个剧集。在这种情况下,所有依赖项都将被视为非常方便(较少配置)的情节。

    配置还说要使用the catalog file

    REWRITE_SYSTEM "http://www.ab.org" "maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!"
    

    这指示 JAXB/XJC 将所有以 http://www.ab.org 开头的架构 URL 重写为以 maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::! 开头。后者会经过maven-jaxb2-plugin处理,最后解析到a中的资源。

    让我们仔细看看。架构b.xsdimports http://www.ab.org/a.xsd

    <import namespace="urn:a" schemaLocation="http://www.ab.org/a.xsd"/>
    

    这将被重写为maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!/a.xsd,这将被解析为项目a 的JAR 中的a.xsd。因此,最后,JAXB/XJC 将能够从a 的 JAR 工件中读取此模式。

    您还可以使用PUBLIC 而不是REWRITE_SYSTEM 来引用每个命名空间URI 的a.xsd 而不是架构位置(这在逻辑上更好):

    PUBLIC "urn:a" "maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!/a.xsd"
    

    但是,如果您的 xs:import 中有 schemaLocation,则此操作无效。

    目前可行:

    <xsd:import namespace="urn:a"/>
    

    这暂时不起作用:

    <xsd:import namespace="urn:a" schemaLocation="a.xsd"/>
    

    我已向 Oracle 发送了一个 pull request 已修复该问题,但尚未应用。

    以上解释适用于maven-jaxb2-plugin,适用于0.10.0 及更高版本。

    您最初的问题是关于来自 Codehaus 的jaxb2-maven-plugin,这是一个不同的 Maven 插件。这个插件没有我上面描述的所有功能,但至少剧集应该通过arguments 工作。 Catalogs 也必须工作,但我相信,jaxb2-maven-plugin 不支持解析 Maven 工件中的模式。您可以改用maven-dependency-plugin 从工件a 中提取a.xsd

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

    审阅者注意:我无意在这里推送/宣传我的插件,我只是想为所提问题提供解决方案。看来我的项目提供了最好/最优雅和完整的解决方案。

    【讨论】:

      【解决方案2】:

      此配置的问题在于 &lt;schemaDirectory&gt; 需要 File 名称/路径。关于File 的事情是它在文件系统上查找文件,从当前工作目录中搜索。在这种情况下,项目根目录。但是项目A的资源不在项目B的src/main/resources中。它是一个类路径资源,其中(在maven中构建时)src/main/resources甚至不再存在。

      我从未尝试过使用jaxb2-maven-plugin,所以我不确定是否可行。

      但是对于maven-jaxb2-plugin,它允许Compiling a schema from a Maven artifact。你可以这样

      <plugin>
          <groupId>org.jvnet.jaxb2.maven2</groupId>
          <artifactId>maven-jaxb2-plugin</artifactId>
          <version>0.9.0</version>
          <executions>
              <execution>
                  <goals>
                      <goal>generate</goal>
                  </goals>
              </execution>
          </executions>
          <configuration>
              <schemas>
                  <schema>
                      <dependencyResource>
                          <groupId>projecta.groupid</groupId>
                          <artifactId>project-a</artifactId>
                          <version>${project.version}</version>
                          <resource>/schema.xsd</resource>
                      </dependencyResource>
                  </schema>
              </schemas>
              <generateDirectory>src/main/gen/</generateDirectory>
              <generatePackage>mypackage</generatePackage> 
          </configuration>
      </plugin>
      

      在这种情况下,它的资源(schema.xsd)在项目A的src/main/resources中。插件将生成类文件到mypackage包并获取src/main/gen

      【讨论】:

      • 很棒,但我想知道是否也可以使用 jaxb2-maven-plugin。
      • 我从未尝试过,但浏览configuration options,我没有看到任何让我相信这是可能的东西。这只是我浏览指南的结果。据我所知,这可能是可能的。我的意思是理论上你可以使用项目 A 的绝对路径,但我认为这违背了你想要完成的目的
      • @peeskillet maven-jaxb2-plugin 的作者在这里。请看我的回答,我想您可能会发现一些有用的功能。 :)
      【解决方案3】:

      我们也可以在 pom.xml 文件中使用如下

              <plugin>
                  <groupId>org.codehaus.mojo</groupId>
                  <artifactId>jaxb2-maven-plugin</artifactId>
                  <version>1.5</version>
                  <executions>
                      <execution>
                          <id>id1</id>
                          <goals>
                              <goal>xjc</goal>
                          </goals>
                          <configuration>
                              <outputDirectory>src/main/java</outputDirectory>
                              <clearOutputDir>false</clearOutputDir>
                              <packageName>com.subu.xsd.model</packageName>
                              <schemaDirectory>src/main/java/schemadir</schemaDirectory>
                              <schemaFiles>XYZ.xsd</schemaFiles>
                          </configuration>
                      </execution>
                  </executions>
              </plugin>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-12
        • 1970-01-01
        • 1970-01-01
        • 2021-10-12
        • 1970-01-01
        相关资源
        最近更新 更多