使用 JAXB 编译多个包含同一元素的重复定义的 XSD

问题描述 投票:0回答:3

问题: 我如何使 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。

我读过有关绑定文件的内容,也许可以解决这个问题,但我不确定如何做到这一点,因此示例将是高度首选。

java xsd jaxb xjc
3个回答
2
投票

根据您的描述,我假设 XSD 文件之间不存在包含关系。另外,我必须假设您正在尝试重用内容重叠的类。

最简单的方法是独立“编译”每个文件,并为每个 XSD 文件提供不同的 Java 包。这里的问题是,如果您尝试将内容从一个 XML 链接到另一个 XML(即从 A 解组,然后编组到 B),则类 C1 位于包 com.A 中,类 C1 位于包 com.B 中,而匹配相同的 XSD 复杂类型,不可“互换”;你必须在它们之间进行转换。您需要自定义绑定文件,或者如果您使用 NetBeans,只需在 JAXB 向导中设置不同的包即可。

最好的方法可能是使用剧集(参见this on SO)。处理 A.xsd,然后使用该情节处理 B.xsd 等


1
投票

您可以使用绑定文件手动解决冲突。以下是示例,您可以在其中为冲突名称指定自定义名称:

<bindings schemaLocation="../party.xsd" version="1.0" node="/xs:schema">
    <bindings node="//xs:complexType[@name='FixedIncomeBook']">
        <class name="PartyFixedIncomeBook"/>
    </bindings>
</bindings>

0
投票

针对

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>
© www.soinside.com 2019 - 2024. All rights reserved.