JAXB 避免 JAXBElement<?> [英] JAXB avoid JAXBElement<?>
问题描述
我想从 XSD 文件生成带有 JAXB 的 Java 类.
I want to generate Java classes with JAXB from a XSD file.
问题是,我总是得到一些像这样的类(删除了命名空间):
The problem is, that I always get a few classes like this one (namespace removed):
public static class Action {
@XmlElementRefs({
@XmlElementRef(name = "ReportStateCanceled", namespace = "http://...", type = JAXBElement.class, required = false),
@XmlElementRef(name = "ReportDate", namespace = "http://...", type = JAXBElement.class, required = false),
@XmlElementRef(name = "ReportStatePreliminary", namespace = "http://...", type = JAXBElement.class, required = false),
@XmlElementRef(name = "DocumentID", namespace = "http://...", type = JAXBElement.class, required = false),
@XmlElementRef(name = "ReportStateNotValidated", namespace = "http://...", type = JAXBElement.class, required = false),
@XmlElementRef(name = "CaseNo", namespace = "http://...", type = JAXBElement.class, required = false),
@XmlElementRef(name = "PatientID", namespace = "http://...", type = JAXBElement.class, required = false),
@XmlElementRef(name = "DocumentKey", namespace = "http://...", type = JAXBElement.class, required = false),
@XmlElementRef(name = "ReportTime", namespace = "http://...", type = JAXBElement.class, required = false),
@XmlElementRef(name = "ReportHeading", namespace = "http://...", type = JAXBElement.class, required = false),
@XmlElementRef(name = "ReportStateComplete", namespace = "http://...", type = JAXBElement.class, required = false)
})
protected List<JAXBElement<?>> documentKeyOrDocumentIDOrPatientID;
@XmlAttribute(name = "name")
protected String name;
@XmlAttribute(name = "Query")
protected String query;
/**
* Gets the value of the documentKeyOrDocumentIDOrPatientID property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the documentKeyOrDocumentIDOrPatientID property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getDocumentKeyOrDocumentIDOrPatientID().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link JAXBElement }{@code <}{@link Template.Page.Actions.Action.ReportDate }{@code >}
* {@link JAXBElement }{@code <}{@link String }{@code >}
* {@link JAXBElement }{@code <}{@link String }{@code >}
* {@link JAXBElement }{@code <}{@link String }{@code >}
* {@link JAXBElement }{@code <}{@link String }{@code >}
* {@link JAXBElement }{@code <}{@link String }{@code >}
* {@link JAXBElement }{@code <}{@link String }{@code >}
* {@link JAXBElement }{@code <}{@link String }{@code >}
* {@link JAXBElement }{@code <}{@link String }{@code >}
* {@link JAXBElement }{@code <}{@link Template.Page.Actions.Action.ReportTime }{@code >}
* {@link JAXBElement }{@code <}{@link String }{@code >}
*
*
*/
public List<JAXBElement<?>> getDocumentKeyOrDocumentIDOrPatientID() {
if (documentKeyOrDocumentIDOrPatientID == null) {
documentKeyOrDocumentIDOrPatientID = new ArrayList<JAXBElement<?>>();
}
return this.documentKeyOrDocumentIDOrPatientID;
}
/**
* Gets the value of the name property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setName(String value) {
this.name = value;
}
/**
* Gets the value of the query property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getQuery() {
return query;
}
/**
* Sets the value of the query property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setQuery(String value) {
this.query = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <simpleContent>
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
* <attribute name="dateFormat" type="{http://www.w3.org/2001/XMLSchema}string" />
* </extension>
* </simpleContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"value"
})
public static class ReportDate {
@XmlValue
protected String value;
@XmlAttribute(name = "dateFormat")
protected String dateFormat;
/**
* Gets the value of the value property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getValue() {
return value;
}
/**
* Sets the value of the value property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setValue(String value) {
this.value = value;
}
/**
* Gets the value of the dateFormat property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getDateFormat() {
return dateFormat;
}
/**
* Sets the value of the dateFormat property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setDateFormat(String value) {
this.dateFormat = value;
}
}
如您所见,JAXB 使用 JAXBElement.这样的类对我来说是不可用的.
As you can see JAXB uses JAXBElement. Such classes are unuseable for me.
经过一番研究,我发现 JAXB 与 nillable="true"
和 minOccurs="0"
一起存在问题,但我没有在任何地方使用 nillable.我很确定,这个问题与 minOccurs
和 maxOccurs
有关.
After some research I found out that JAXB has troubles with nillable="true"
and minOccurs="0"
together, but I do not use nillable anywhere. Tough I am sure, that the problem is related with the minOccurs
and maxOccurs
.
即使我知道确切的问题,这也是个问题,因为我从外部人员那里获得了 XSD,并且不允许我对其进行修改.
Even if I would know the exact problem it would be a problem because I get the XSD from an external person and I am not allowed to modify it.
XSD 片段:
<xs:element name="Action" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="DocumentKey" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="DocumentID" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="PatientID" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="CaseNo" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="ReportHeading" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="ReportDate" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string" >
<xs:attribute name="dateFormat" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="ReportTime" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string" >
<xs:attribute name="timeFormat" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="ReportStateNotValidated" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="ReportStatePreliminary" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="ReportStateComplete" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="ReportStateCanceled" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="Query" type="xs:string" />
</xs:complexType>
</xs:element>
所以我寻找另一种解决方案.我总是得出的结论是,如果在从 XSD 生成类时添加 jaxb-binding.xml,我可以解决问题.
So I searched for another solution. I always came to the conclusion that I could solve the problem if add a jaxb-binding.xml when I am generating the classes from the XSD.
我尝试了一些绑定,但都没有成功.
I tried some bindings, but it never worked.
使用此绑定,我得到的 JAXBElement 更少,但我得到的是接口而不是类.
With this binding I get less JAXBElements, but I get interfaces instead of classes.
<xs:schema 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"
jaxb:version="2.0">
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings generateValueClass="false" generateElementProperty="false" >
<xjc:simple />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
</xs:schema>
<小时>
现在我问是否有人知道解决方案?最好的解决方案是,如果有人为我提供了一个有效的 jaxb-binding.xml.
And now I am asking if anyone knows a solution? The best solution would be if someone provides me a working jaxb-binding.xml.
我使用的是 xjc 编译器的 2.2.4-2 版本.
I am using version 2.2.4-2 of the xjc compiler.
提前谢谢你!
推荐答案
问题
问题在于您的 xs:choice
元素具有 maxOccurs="unbounded"
.
<xs:choice minOccurs="0" maxOccurs="unbounded">
JAXB 规范参考
因为这个 JAXB 不能为选择结构中的每个选项生成单独的属性.有关详细信息,请参阅 JAXB 2.2 (JSR-222) 规范的6.12.6 绑定重复出现模型组":
Because of this JAXB can't generate individual properties for each option in the choice structure. See "6.12.6 Bind a repeating occurrence model group" of the JAXB 2.2 (JSR-222) specification for more details:
为什么会出现问题
以下 XML 片段根据您的 XML 架构是有效的,并且需要能够在生成的对象模型中表示.
The following XML fragment is valid according to your XML schema and needs to be able to be represented in the generated object model.
<Action>
<DocumentID/>
<PatientID/>
<PatientID/>
<DocumentID/>
</Action>
解决方法
如果您真的不喜欢 JAXB 生成的类,您可以创建自己的类,并通过绑定文件指定 JAXB 应该使用它而不是创建新类.
Work Around
If you ever really don't like a class that JAXB generates you can create your own and specify via a bindings file that JAXB should use it instead of creating a new one.
<jxb:bindings schemaLocation="yourSchema.xsd">
<jxb:bindings node="//xs:element[@name='Action']">
<jxb:class ref="com.example.Action"/>
</jxb:bindings>
</jxb:bindings>
这篇关于JAXB 避免 JAXBElement<?>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!