我的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>
答案 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>