JAXB生成Java类遇属性冲突,绑定文件配置报错咨询
解决JAXB生成Java类时的属性冲突问题
问题描述
我需要基于以下XSD Schema片段生成Java类:
<xsd:complexType name="Instruction"> <xsd:choice> <xsd:sequence> <xsd:element name="InstructionIndicator" type="InstructionIndicator"> <xsd:annotation> <xsd:documentation>some text</xsd:documentation> </xsd:annotation> </xsd:element> <xsd:sequence minOccurs="0" maxOccurs="49"> <xsd:element name="MultipleTimingModifier" type="ANDOR" minOccurs="0"> <xsd:annotation> <xsd:documentation>some text</xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element name="TimingAndDuration" type="TimingAndDuration" /> </xsd:sequence> </xsd:sequence> <xsd:sequence> <xsd:choice> <xsd:element name="AdministrationIndicator" type="AdministrationIndicator"> <xsd:annotation> <xsd:documentation>some text</xsd:documentation> </xsd:annotation> </xsd:element> <xsd:sequence> <xsd:element name="DoseAdministration" type="DoseAdministration" /> <xsd:element name="TimingAndDuration" type="TimingAndDuration"> <xsd:annotation> <xsd:documentation>some text</xsd:documentation> </xsd:annotation> </xsd:element> <xsd:sequence minOccurs="0" maxOccurs="49"> <xsd:element name="MultipleTimingModifier" type="ANDOR" minOccurs="0"> <xsd:annotation> <xsd:documentation>some text</xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element name="TimingAndDuration" type="TimingAndDuration" /> </xsd:sequence> </xsd:sequence> </xsd:choice> <xsd:sequence minOccurs="0"> <xsd:element name="IndicationForUse" type="Indication" maxOccurs="50"> <xsd:annotation> <xsd:documentation>some text</xsd:documentation> </xsd:annotation> </xsd:element> <xsd:element name="IndicationClarifyingFreeText" type="an1..255" minOccurs="0" /> </xsd:sequence> <xsd:element name="MaximumDoseRestriction" type="MaximumDoseRestriction" minOccurs="0" maxOccurs="50"> <xsd:annotation> <xsd:documentation>some text</xsd:documentation> </xsd:annotation> </xsd:element> </xsd:sequence> </xsd:choice> </xsd:complexType>
处理这个Schema时,我遇到了JAXB属性冲突错误:
Property 'MultipleTimingModifierAndTimingAndDuration' is already defined. Use <jaxb:property> to resolve this conflict
尝试的解决方案及新问题
为了解决这个冲突,我编写了如下绑定文件:
<jaxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc" version="2.0"> <jaxb:bindings schemaLocation="structures.xsd" node="//xs:complexType[@name='Instruction']/xs:choice[1]/xs:sequence[1]/xs:sequence/xs:element[@name='MultipleTimingModifier']"> <jaxb:property name="MultipleTimingModifier1" /> </jaxb:bindings> <jaxb:bindings schemaLocation="structures.xsd" node="//xs:complexType[@name='Instruction']/xs:choice/xs:sequence[1]/xs:sequence/xs:element[@name='TimingAndDuration']"> <jaxb:property name="TimingAndDuration1" /> </jaxb:bindings> </jaxb:bindings>
但在Eclipse中使用该绑定文件生成JAXB类时,又出现了新错误:
compiler was unable to honor this property customization. It is attached to a wrong place, or its inconsistent with other bindings
补充说明:如果移除目标<sequence>节点的maxOccurs="49"约束,就能成功生成类;该Schema由5个文件组成,共2000多行,这里只分享了出错相关的部分。
正确的解决方案
问题出在你的绑定文件定位错了节点——JAXB的属性冲突是因为两个结构完全相同的<xsd:sequence>(都包含MultipleTimingModifier和TimingAndDuration,且都设置了maxOccurs>1)会生成同名的列表属性。你需要给这两个sequence节点本身指定不同的属性名,而不是给sequence内部的element改名。
以下是修正后的绑定文件:
<jaxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc" version="2.0"> <!-- 绑定第一个重复的sequence节点(位于choice的第一个sequence分支下) --> <jaxb:bindings schemaLocation="structures.xsd" node="//xs:complexType[@name='Instruction']/xs:choice/xs:sequence[1]/xs:sequence[2]"> <jaxb:property name="TimingModifiersGroup1"/> </jaxb:bindings> <!-- 绑定第二个重复的sequence节点(位于choice的第二个sequence分支的内部sequence下) --> <jaxb:bindings schemaLocation="structures.xsd" node="//xs:complexType[@name='Instruction']/xs:choice/xs:sequence[2]/xs:choice/xs:sequence[2]/xs:sequence[2]"> <jaxb:property name="TimingModifiersGroup2"/> </jaxb:bindings> </jaxb:bindings>
解释
- 第一个XPath定位到的是
Instruction复杂类型中,第一个<xsd:sequence>(包含InstructionIndicator的那个)内部的第二个<xsd:sequence>(也就是带maxOccurs="49"的那个)。 - 第二个XPath定位到的是
Instruction复杂类型中,第二个<xsd:sequence>分支里,内部choice的第二个<xsd:sequence>(包含DoseAdministration的那个)下的第二个<xsd:sequence>(同样带maxOccurs="49")。 - 通过给这两个sequence节点指定不同的
jaxb:property名称,JAXB会为它们生成不同的Java属性(比如List<TimingModifiersGroup1>和List<TimingModifiersGroup2>),从而解决属性名冲突问题。
内容的提问来源于stack exchange,提问作者Abdul Ahad
相关产品推荐
相关产品推荐

