JAXB避免使用JAXBElement<?> [英] JAXB avoid JAXBElement<?>

查看:98
本文介绍了JAXB避免使用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>
             * &lt;complexType>
             *   &lt;simpleContent>
             *     &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string">
             *       &lt;attribute name="dateFormat" type="{http://www.w3.org/2001/XMLSchema}string" />
             *     &lt;/extension>
             *   &lt;/simpleContent>
             * &lt;/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&lt;?&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆