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尝试了一些绑定,但它从未奏效。
I tried some bindings, but it never worked.
通过这种绑定,我得到的JAXBElements更少,但我得到的是接口而不是类。
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 Spec Reference
由于这个原因,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:
- https://jcp.org/en/jsr/detail?id=222
为什么会出现问题
以下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屋!