JAXB在1个IDREF和1个以上之间存在不一致

时间:2010-07-02 23:16:51

标签: java xsd jaxb

所以一直在使用ID和IDREF在JAXB阅读了here,并且在该示例中呈现他们利用1个IDREF元件,其表现为在生成的Java代码的一个对象。我包括XML Schema ...

<xsd:complexType name="CustomerType">
  <xsd:sequence>
    <xsd:element name="id"   type="xsd:ID"/>
    <xsd:element name="name" type="xsd:string"/>
  </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="OrderType">
  <xsd:sequence>
    <xsd:choice>
      <xsd:element name="customer" type="CustomerType"/>
      <xsd:element name="custref"  type="xsd:IDREF"/>
    </xsd:choice>
    <xsd:element name="items" type="ItemType" maxOccurs="unbounded"/>
  </xsd:sequence>
</xsd:complexType>

和后代的Java代码。

public class OrderType {

    protected CustomerType customer;
    protected Object custref;
    protected List items;

    public CustomerType getCustomer() {
        return customer;
    }

    public void setCustomer(CustomerType value) {
        this.customer = value;
    }

    public Object getCustref() {
        return custref;
    }

    public void setCustref(Object value) {
        this.custref = value;
    }

    public List getItems() {
        if (items == null) {
            items = new ArrayList();
        }
        return this.items;
    }
}

现在,在我的代码中,我尝试了一些不同的东西,例如以下架构:

<xsd:complexType name="SimViewType">
    <xsd:sequence>
        <xsd:element name="NAME" type="xsd:string"></xsd:element>
        <xsd:element name="ITEM" type="am:SimItemIDREF" minOccurs="0" maxOccurs="unbounded"></xsd:element>
    </xsd:sequence>
    <xsd:attribute name="id" type="xsd:ID" use="required"></xsd:attribute>
</xsd:complexType>

<xsd:simpleType name="SimItemIDREF">
    <xsd:restriction base="xsd:IDREF"></xsd:restriction>
</xsd:simpleType>

虽然我附上了一个带有SimItemIDREF的通用IDREF,但它只是为了提高可读性。但是,即使我使用普通的xsd:IDREF,简单的事实是我使用的值不是1意味着我的Java代码最终得到以下内容......

public class SimViewType {
    ...
    protected List<JAXBElement<Object>> item;
    ...
}

而不是List<Object>,我得到List<JAXElement<Object>>。现在,如果我想打一个JAXElement,我能做到这一点很好,但由于之间不存在转换我不能将其添加到我的SimViewType JAXElement<SimItemType>JAXElement<Object>。 SimViews实际上不能控制SimItems的想法在我的设计中至关重要,因此简单地删除引用并不是一个好主意,因为它可能会在运行时产生危险的差异。

我如何创建一个SimItemType或JAXBElement,以便我可以将它与我的SimViewType一起使用?

2 个答案:

答案 0 :(得分:0)

XJC使用createSimViewTypeITEM方法生成ObjectFactory以创建ITEM元素。

/**
 * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}}
 * 
 */
@XmlElementDecl(namespace = "", name = "ITEM", scope = SimViewType.class)
@XmlIDREF
public JAXBElement<Object> createSimViewTypeITEM(Object value) {
    return new JAXBElement<Object>(_SimViewTypeITEM_QNAME, Object.class, SimViewType.class, value);
}

有帮助吗?

答案 1 :(得分:0)

您可以按如下方式注释您的架构以获得所需的类:

<xsd:schema 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns="http://www.mycompany.org/exchange" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    targetNamespace="http://www.mycompany.org/exchange" 
    elementFormDefault="qualified" attributeFormDefault="unqualified"
    jaxb:version="2.1"> 

    <xsd:complexType name="CustomerType"> 
        <xsd:sequence> 
            <xsd:element name="id"   type="xsd:ID"/> 
            <xsd:element name="name" type="xsd:string"/> 
        </xsd:sequence> 
    </xsd:complexType> 

    <xsd:complexType name="OrderType"> 
        <xsd:sequence> 
            <xsd:choice> 
                <xsd:element name="customer" type="CustomerType"/> 
                <xsd:element name="custref"  type="xsd:IDREF"> 
                    <xsd:annotation>
                        <xsd:appinfo>
                            <jaxb:property>
                                <jaxb:baseType name="org.mycompany.exchange.CustomerType"/>
                            </jaxb:property>
                        </xsd:appinfo>
                    </xsd:annotation>
                </xsd:element>
            </xsd:choice> 
            <!--xsd:element name="items" type="ItemType" maxOccurs="unbounded"/--> 
        </xsd:sequence> 
    </xsd:complexType> 

</xsd:schema>

以下是结果类:

package org.mycompany.exchange;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlIDREF;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "OrderType", propOrder = {
    "customer",
    "custref"
})
public class OrderType {

    protected org.mycompany.exchange.CustomerType customer;
    @XmlElement(type = Object.class)
    @XmlIDREF
    @XmlSchemaType(name = "IDREF")
    protected org.mycompany.exchange.CustomerType custref;

    public org.mycompany.exchange.CustomerType getCustomer() {
        return customer;
    }

    public void setCustomer(org.mycompany.exchange.CustomerType value) {
        this.customer = value;
    }

    public org.mycompany.exchange.CustomerType getCustref() {
        return custref;
    }

    public void setCustref(org.mycompany.exchange.CustomerType value) {
        this.custref = value;
    }

}