我想从XSD文件中使用JAXB生成Java类。
问题是,我总是得到一些像这样的类(删除命名空间):
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。这些课程对我来说无法使用。
经过一番研究后,我发现JAXB与nillable="true"
和minOccurs="0"
一起出现问题,但我不会在任何地方使用nillable。我很确定,问题与minOccurs
和maxOccurs
。
即使我知道确切的问题也会出现问题,因为我从外部人那里得到了XSD,我不允许修改它。
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,我可以解决问题。
我尝试了一些绑定,但它从未奏效。
通过这种绑定,我获得了更少的JAXBElements,但是我获得了接口而不是类。
<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。
我使用的是xjc编译器的2.2.4-2版本。
提前谢谢!
答案 0 :(得分:5)
我完全为这个问题写了Simpify plugin。
<xs:schema ...
xmlns:simplify="http://jaxb2-commons.dev.java.net/basic/simplify"
jaxb:extensionBindingPrefixes="... simplify">
<xs:complexType name="typeWithReferencesProperty">
<xs:choice maxOccurs="unbounded">
<xs:element name="a" type="someType">
<xs:annotation>
<xs:appinfo>
<simplify:as-element-property/>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="b" type="someType"/>
</xs:choice>
</xs:complexType>
会给你
@XmlElement(name = "a")
protected List<SomeType> a;
@XmlElement(name = "b")
protected List<SomeType> b;
而不是
@XmlElementRefs({
@XmlElementRef(name = "a", type = JAXBElement.class),
@XmlElementRef(name = "b", type = JAXBElement.class)
})
protected List<JAXBElement<SomeType>> aOrB;
免责声明:我是作者。
答案 1 :(得分:3)
问题是您的xs:choice
元素有maxOccurs="unbounded"
。
<xs:choice minOccurs="0" maxOccurs="unbounded">
JAXB规范参考
因为这个JAXB无法为选择结构中的每个选项生成单独的属性。有关更多详细信息,请参阅JAXB 2.2(JSR-222)规范的“6.12.6绑定重复发生模型组”:
为什么会出现问题
以下XML片段根据您的XML架构有效,并且需要能够在生成的对象模型中表示。
<Action>
<DocumentID/>
<PatientID/>
<PatientID/>
<DocumentID/>
</Action>
如果您真的不喜欢JAXB生成的类,您可以创建自己的类,并通过绑定文件指定JAXB应该使用它而不是创建新的。
<jxb:bindings schemaLocation="yourSchema.xsd">
<jxb:bindings node="//xs:element[@name='Action']">
<jxb:class ref="com.example.Action"/>
</jxb:bindings>
</jxb:bindings>