【发布时间】:2018-02-23 11:59:26
【问题描述】:
我想通过XSDs 生成java 类,我想在另一个文件中使用/包含一个XSD 文件,但是当我将它们包含在另一个XSDs 中时,两个包中都会生成相同的java 类.我也在使用maven-jaxb2-plugin插件
【问题讨论】:
我想通过XSDs 生成java 类,我想在另一个文件中使用/包含一个XSD 文件,但是当我将它们包含在另一个XSDs 中时,两个包中都会生成相同的java 类.我也在使用maven-jaxb2-plugin插件
【问题讨论】:
使用所谓的剧集执行separate - aka modular - schema compilation。也就是说,如果要将模式 A 导入模式 B 并为模式 B 生成类,则首先创建一个单独的 Maven 项目,以便像往常一样使用 maven-jaxb2-plugin 将模式 A 编译为单独的 Maven 工件。 (这是假设架构 A 独立存在,即不导入任何其他架构;否则您必须对导入的架构重复相同的过程。)结果,您将获得带有生成类的 A.jar 仅来自模式 A,最重要的是,META-INF/sun-jaxb.episode 文件。此文件提供有关现有 XSD 到 Java 绑定的信息,这将告诉 maven-jaxb2-plugin(实际上是 maven-jaxb2-plugin 底层的 xjc 工具)已经从模式生成了什么,因此阻止它再次重新生成相同的类。
然后您创建另一个 Maven 项目以编译模式 B,在其 Maven 依赖项中包含 A.jar 的 Maven 工件。这次,在 maven-jaxb2-plugin 的配置中,将配置参数 useDependenciesAsEpisodes 设置为 true。这将告诉插件使用来自所有依赖项的.episode 文件(如果有的话)。您可以在插件的GitHub wiki 上找到一个基本示例。下面是来自AuthzForce 项目的真实示例,它是一个 XACML 实现,其中 OASIS XACML standard schema (xacml-core-v3-schema-wd-17.xsd) 导入 W3C 标准 XML 命名空间模式 (xml.xsd)。因此,您有一个 Maven project/artifact for the xml.xsd 和 another one for the XACML schema,其中 POM 的相关部分如下所示:
<project ...>
...
<dependencies>
...
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${artifactId.prefix}-xmlns-model</artifactId>
<version>${project.parent.version}</version>
</dependency>
...
</dependencies>
<build>
<plugins>
...
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<configuration>
<verbose>true</verbose>
<extension>true</extension>
<strict>false</strict>
<useDependenciesAsEpisodes>true</useDependenciesAsEpisodes>
...
<catalog>src/main/jaxb/catalog.xml</catalog>
<schemaDirectory>src/main/resources</schemaDirectory>
<schemaIncludes>
<include>xacml-core-v3-schema-wd-17.xsd</include>
</schemaIncludes>
</configuration>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
您注意到还有一个目录参数指向 XML 目录文件。这也很重要,因为此目录将使插件能够直接在其 maven 工件中定位 A.xsd 文件(在我的示例中为 xml.xsd),因此您无需在项目 B 或其他地方复制该文件。在我的示例中,由于 XACML 架构按如下方式导入 xml.xsd:
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
...catalog.xml 必须如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="http://www.w3.org/2001/xml.xsd" uri="maven:org.ow2.authzforce:authzforce-ce-xmlns-model:jar!/xml.xsd" />
</catalog>
您注意到 uri 参数从其 Maven 工件中引用了 xml.xsd。有关此语法以引用 Maven 工件资源的更多信息,请参阅maven-jaxb2-plugin's wiki。
一般来说,为了在管理模式位置时实现最大的灵活性和简单性,我建议仅在模式导入中指定命名空间。 (没有schemaLocation。)例如,喜欢这个:
<xs:import namespace="http://www.w3.org/XML/1998/namespace" />
...在这种情况下,catalog.xml 应该如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<public publicId="http://www.w3.org/XML/1998/namespace" uri="maven:org.ow2.authzforce:authzforce-ce-xmlns-model:jar!/xml.xsd" />
</catalog>
(在我的示例中并非如此,因为标准委员会的官方 XACML 架构使用 schemaLocation,因此最好保持原样。)
【讨论】: