Jaxb生成的问题

时间:2016-07-11 13:25:08

标签: maven xsd jaxb

我的JAXB代有问题。我有两个XSD(都在相同的层次结构中),它们具有非常相似的模式定义:

A.xsd

<xs:schema>
  <xs:element name="A">
    <xs:complexType>
        <xs:sequence>
          <xs:element name="CacheInfo">
            <xs:complexType>
              <xs:complexContent>
                <xs:extension base="CacheType">
                  <xs:sequence ... />
                </xs:extension>
              </xs:complexContent>
            </xs:complexType>
         </xs:element> <!--CacheInfo -->
       </xs:sequence>
     </xs:complexType>
  </xs:element> <!-- A -->
  <xs:complexType name="CacheType" ... />
  <xs:complexType name="TimeType" ... />
</xs:schema>

B.xsd

<xs:schema>
  <xs:element name="B">
    <xs:complexType>
      <xs:sequence>
        <xs:choice>
          <xs:element name="CacheInfo" type="CacheType">
         </xs:element> <!--CacheInfo -->
        <xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element> <!-- B -->
  <xs:complexType name="CacheType" ... />
  <xs:complexType name="TimeType" ... />
</xs:schema>

这两个XSD中的CacheType结构不同。它的名字也一样。

我现在的问题是,当我尝试生成代码时出现此错误: [错误]档案:A.xsd [95,38] org.xml.sax.SAXParseException; systemId:file:A.xsd; lineNumber:95; columnNumber:38; &#39; CacheType&#39;已定义(TimeType的相同问题)

当我删除其中一个文件时,生成就可以了。我无法编辑XSD,因此我需要一个绑定文件来重命名两种特殊情况的类型:

<bindings schemaLocation="../xsd/A.xsd" node="//xs:complexType[@name='CacheType']">
        <class name="ACacheType" />
</bindings>
<bindings schemaLocation="../xsd/B.xsd" node="//xs:complexType[@name='CacheType']">
        <class name="BCacheType" />
</bindings>

但这不起作用。 当我尝试将类型绑定到属性时,它也无法工作(我最终会出现同样的错误):

<bindings schemaLocation="../xsd/A.xsd">
    <bindings node="//xs:complexType[@name='CacheType']">
        <property name="ACacheType" />
    </bindings>
    <bindings node=".//xs:complexType[@name='TimeType']">
        <property name="ATimeType" />
    </bindings>
</bindings>
<bindings schemaLocation="../xsd/B.xsd">
    <bindings node="//xs:complexType[@name='CacheType']">
        <property name="BCacheType" />
    </bindings>
    <bindings node=".//xs:complexType[@name='TimeType']">
        <class name="BTimeType" />
    </bindings>
</bindings>

有什么我看不到的吗?为什么我不能用这些绑定生成这两个XSD? 要完成此操作,请参阅我的pom.xml代码段:

<plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>jaxb2-maven-plugin</artifactId>
                <version>2.2</version>
                <executions>
                    <execution>
                        <id>generate-htng-sources</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>xjc</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

2 个答案:

答案 0 :(得分:0)

您需要在自己的包中定义它们 这将生成相同的类但在不同的包中,因此它不会成为问题。

<jaxb:bindings schemaLocation="../xsd/A.xsd">
    <jaxb:schemaBindings>
        <jaxb:package name="packagea" />
    </jaxb:schemaBindings>
</jaxb:bindings>

<jaxb:bindings schemaLocation="../xsd/B.xsd">
    <jaxb:schemaBindings>
        <jaxb:package name="packageb" />
    </jaxb:schemaBindings>
</jaxb:bindings>

我没有使用过这个插件。我使用以下内容:

        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.12.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                    <configuration>
                        <schemaDirectory>src/main/resources/xsd</schemaDirectory>
                        <bindingDirectory>src/main/resources/xsd</bindingDirectory>
                        <bindingIncludes>
                            <include>*.xjb</include>
                        </bindingIncludes>
                        <generateDirectory>${project.build.directory}/generated-sources</generateDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>

您也可以尝试使用它来查看是否有任何错误。

答案 1 :(得分:0)

First, I'd ensure that the binding files are in the location expected by the jaxb2-maven-plugin. Specifying a package with a schemaBinding as mentioned by @Apostolos should have worked even without changing the plugin as I read the docs.

If the binding files are being applied, then one thing I notice is the bindings mentioned in the original question use a mix of property and class:

<bindings schemaLocation="../xsd/A.xsd">
  <bindings node="//xs:complexType[@name='CacheType']">
    <property name="ACacheType" />                         <!-- property -->
  </bindings>
  <bindings node=".//xs:complexType[@name='TimeType']">
    <property name="ATimeType" />                          <!-- property -->
  </bindings>
</bindings>
<bindings schemaLocation="../xsd/B.xsd">
  <bindings node="//xs:complexType[@name='CacheType']">
    <property name="BCacheType" />                         <!-- property -->
  </bindings>
  <bindings node=".//xs:complexType[@name='TimeType']">
    <class name="BTimeType" />                             <!-- class -->
  </bindings>
</bindings>

This document from Oracle has a section near the bottom on resolving conflicts. One example shows an element with name 'Class' which is a Java reserved word. They fix the conflict by specifying both property and class:

<jxb:bindings node="//xs:element[@name='Class']">
  <jxb:class name="Clazz"/>
  <jxb:property name="Clazz"/>
</jxb:bindings> 

So I wonder, does it work if the binding is modified to specify both?

<bindings schemaLocation="../xsd/A.xsd">
  <bindings node="//xs:complexType[@name='CacheType']">
    <class name="ACacheType" />
    <property name="ACacheType" />
  </bindings>
  ... repeat for TimeType ....
</bindings>