问题: 我如何使 xjc/Jaxb 为同一名称空间中包含重复元素定义的多个模式生成正确的 javaclass?
信息: 我有三个 .xsd 模式:A、B 和 C。它们都具有相同的目标命名空间。 它们都是给我的 3 个 shemas,我无论如何都不允许以任何方式改变它们。
他们 A 有一些在 B 或 C 中也可以找到的元素(但 A 也有很多自我声明的元素) 示例:A 和 C 的“代码”相同:
<xs:simpleType name="y_ym_ymdDatoType">
<xs:union memberTypes="arcgYearType arcgYearMonthType arcDateType"/>
</xs:simpleType>
<xs:simpleType name="arcgYearType">
<xs:restriction base="xs:gYear">
<xs:minInclusive value="1700"/>
<xs:maxInclusive value="2100"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="arcgYearMonthType">
<xs:restriction base="xs:gYearMonth">
<xs:minInclusive value="1700-01"/>
<xs:maxInclusive value="2100-12"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="arcDateType">
<xs:restriction base="xs:date">
<xs:minInclusive value="1700-01-01"/>
<xs:maxInclusive value="2100-12-31"/>
</xs:restriction>
</xs:simpleType>
当使用xjc将它们编译成javaclasses时,我得到以下异常:
[ERROR] 'y_ym_ymdDatoType' is already defined
line 297 of file:../c.xsd
[ERROR] (related to above error) the first definition appears here
line 309 of file:../a.xsd
同样的情况也发生在其他元素上:arcgYearType、arcgYearMonthType 和 arcDateType。
我读过有关绑定文件的内容,也许可以解决这个问题,但我不确定如何做到这一点,因此示例将是高度首选。
根据您的描述,我假设 XSD 文件之间不存在包含关系。另外,我必须假设您正在尝试重用内容重叠的类。
最简单的方法是独立“编译”每个文件,并为每个 XSD 文件提供不同的 Java 包。这里的问题是,如果您尝试将内容从一个 XML 链接到另一个 XML(即从 A 解组,然后编组到 B),则类 C1 位于包 com.A 中,类 C1 位于包 com.B 中,而匹配相同的 XSD 复杂类型,不可“互换”;你必须在它们之间进行转换。您需要自定义绑定文件,或者如果您使用 NetBeans,只需在 JAXB 向导中设置不同的包即可。
最好的方法可能是使用剧集(参见this on SO)。处理 A.xsd,然后使用该情节处理 B.xsd 等
您可以使用绑定文件手动解决冲突。以下是示例,您可以在其中为冲突名称指定自定义名称:
<bindings schemaLocation="../party.xsd" version="1.0" node="/xs:schema">
<bindings node="//xs:complexType[@name='FixedIncomeBook']">
<class name="PartyFixedIncomeBook"/>
</bindings>
</bindings>
针对
A.xsd
包含公共类并同时包含在 B.xsd
和 C.xsd
中的情况的解决方案。
该解决方案已使用
maven-jaxb-plugin
版本 3.1.0
进行了测试。
你必须制作4个XJB文件:
A.xjb
和 AClasses.xjb
适用于 A.xsd
B.xjb
适用于 B.xsd
C.xjb
适用于 C.xsd
A.xjb
将常用类型放入 common
Java 包中:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings version="3.0" xmlns="https://jakarta.ee/xml/ns/jaxb">
<bindings scd="x-schema::tns" xmlns:tns="https://targetnamespace">
<schemaBindings>
<package name="common"/>
</schemaBindings>
</bindings>
</bindings>
AClasses.xjb
将指示 B.xsd
和 C.xsd
重用 common
Java 包中的常见类型:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings version="3.0" xmlns="https://jakarta.ee/xml/ns/jaxb">
<bindings scd="x-schema::tns" xmlns:tns="https://targetnamespace">
<bindings scd="~tns:CommonType1">
<class ref="common.CommonType1"/>
</bindings>
<bindings scd="~tns:CommonType2">
<class ref="common.CommonType2"/>
</bindings>
<!-- ... -->
</bindings>
</bindings>
请注意,
maven-jaxb-plugin
可以通过在 AClasses.xjb
上执行来为您生成大部分 A.xsd
文件。执行后查看target/classes/META-INF/JAXB
目录。
B.xjb
会将 B.xsd
特定类型放入 package1
:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings version="3.0" xmlns="https://jakarta.ee/xml/ns/jaxb">
<bindings scd="x-schema::tns" xmlns:tns="https://targetnamespace">
<schemaBindings>
<package name="package1"/>
</schemaBindings>
</bindings>
</bindings>
C.xjb
会将 C.xsd
特定类型放入 package2
:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings version="3.0" xmlns="https://jakarta.ee/xml/ns/jaxb">
<bindings scd="x-schema::tns" xmlns:tns="https://targetnamespace">
<schemaBindings>
<package name="package2"/>
</schemaBindings>
</bindings>
</bindings>
最后,您必须在
maven-jaxb-plugin
中定义 3 个 pom.xml
执行:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>3.1.0</version>
<!-- Common configuration for all executions -->
<configuration>
<clearOutputDir>false</clearOutputDir>
</configuration>
<executions>
<execution>
<id>xjc-a</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sources>
<source>A.xsd</source>
</sources>
<xjbSources>
<xjbSource>A.xjb</xjbSource>
</xjbSources>
</configuration>
</execution>
<execution>
<id>xjc-b</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sources>
<source>B.xsd</source>
</sources>
<xjbSources>
<xjbSource>AClasses.xjb</xjbSource>
<xjbSource>B.xjb</xjbSource>
</xjbSources>
</configuration>
</execution>
<execution>
<id>xjc-c</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sources>
<source>C.xsd</source>
</sources>
<xjbSources>
<xjbSource>AClasses.xjb</xjbSource>
<xjbSource>C.xjb</xjbSource>
</xjbSources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>