如何使用JAXB XJC从外部XSD文件生成类

时间:2014-10-10 09:54:31

标签: java jaxb xsd xjc

我有两个项目:

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

乙 / SRC /主/根 的pom.xml

我想在B项目中生成来自XSD的类,它存在于A Project

在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?

3 个答案:

答案 0 :(得分:6)

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

如何做到这一点:

  • 将您的工件a添加为剧集。
  • 如果将a.xsd导入b.xsd,则必须在编译b时将此架构提供给JAXB:
    • 一种方法是使用Maven依赖插件从工件a.xsd中提取a
    • 另一种方法是使用目录文件将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.xsd imports 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.xsd的JAR内的a。因此,最后,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"

但如果schemaLocation中有xs:import,则bug in JAXB/XJC这不起作用。

目前可行:

<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.xsd中提取a

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

评论者注意:我不打算推​​广/宣传我的插件,我只想提出问题的解决方案。我的项目似乎提供了最好/最优雅和完整的解决方案。

答案 1 :(得分:4)

此配置的问题是<schemaDirectory>需要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 < / p>

答案 2 :(得分:0)

我们也可以在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>
相关问题