3

Here is the XSD schema that i created for a WS

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified" attributeFormDefault="unqualified">

<xs:element name="shipmentStatus" type="shipmentStatusType" />

<xs:complexType name="shipmentStatusType">
    <xs:sequence>
        <xs:element name="orderNumber" type="xs:int"/>
    </xs:sequence>

    <xs:attribute name="requestStatus">
        <xs:simpleType>
            <xs:restriction base="xs:string">
                <xs:enumeration value="SHIPPED"/>
                <xs:enumeration value="PENDING"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:attribute>

</xs:complexType>

When i generated Java classes using JAXB 2.1, it generated only one class i.e. shipmentStatusType. I was expecting that it will generate requestStatus as a JAVA Enum but it didn't. Is it an expected behaviour or did i miss something?

Em Ae
  • 8,167
  • 27
  • 95
  • 162

2 Answers2

4

Just extract your enum/simple type declaration to top-level one and use it as type of the XML attribute:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.example.com" xmlns="http://www.example.com"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    attributeFormDefault="unqualified">

    <xs:simpleType name="requestStatus">
        <xs:restriction base="xs:string">
            <xs:enumeration value="SHIPPED" />
            <xs:enumeration value="PENDING" />
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="shipmentStatus">
        <xs:sequence>
            <xs:element name="orderNumber" type="xs:int" />
        </xs:sequence>
        <xs:attribute name="requestStatus" type="requestStatus" />
    </xs:complexType>

    <xs:element name="shipmentStatus" type="shipmentStatus" />

</xs:schema>

It will give you such an enum:

/**
 * <p>Java class for requestStatus.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * <p>
 * <pre>
 * &lt;simpleType name="requestStatus">
 *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
 *     &lt;enumeration value="SHIPPED"/>
 *     &lt;enumeration value="PENDING"/>
 *   &lt;/restriction>
 * &lt;/simpleType>
 * </pre>
 * 
 */
@XmlType(name = "requestStatus")
@XmlEnum
public enum RequestStatus {

    SHIPPED,
    PENDING;

    public String value() {
        return name();
    }

    public static RequestStatus fromValue(String v) {
        return valueOf(v);
    }

}

and class having it:

/**
 * <p>Java class for shipmentStatus complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="shipmentStatus">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="orderNumber" type="{http://www.w3.org/2001/XMLSchema}int"/>
 *       &lt;/sequence>
 *       &lt;attribute name="requestStatus" type="{http://www.example.com}requestStatus" />
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "shipmentStatus", propOrder = {
    "orderNumber"
})
public class ShipmentStatus {

    protected int orderNumber;
    @XmlAttribute(name = "requestStatus")
    protected RequestStatus requestStatus;

    /**
     * Gets the value of the orderNumber property.
     * 
     */
    public int getOrderNumber() {
        return orderNumber;
    }

    /**
     * Sets the value of the orderNumber property.
     * 
     */
    public void setOrderNumber(int value) {
        this.orderNumber = value;
    }

    /**
     * Gets the value of the requestStatus property.
     * 
     * @return
     *     possible object is
     *     {@link RequestStatus }
     *     
     */
    public RequestStatus getRequestStatus() {
        return requestStatus;
    }

    /**
     * Sets the value of the requestStatus property.
     * 
     * @param value
     *     allowed object is
     *     {@link RequestStatus }
     *     
     */
    public void setRequestStatus(RequestStatus value) {
        this.requestStatus = value;
    }

}
  • 1
    You don't have to make the type global to make it work. There are cases where XSD cannot or should not be changed. For the provided XSD, the solution is actually to use a custom binding file. – Petru Gardea Aug 14 '12 at 01:50
1

I think that you're asking the same thing as this SO post. You need to create a custom binding file to map this simple type to an enumeration.

The binding file:

<jaxb:bindings 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" version="2.1"> 
    <jaxb:globalBindings generateIsSetMethod="true" fixedAttributeAsConstantProperty="true"> 
        <xjc:serializable/> 
    </jaxb:globalBindings> 
    <jaxb:bindings schemaLocation="file:/..../restricting-xml-attribute-to-enum-values.xsd"> 
        <jaxb:bindings node="//xs:complexType[@name='shipmentStatusType']/xs:attribute[@name='requestStatus']/xs:simpleType"> 
            <jaxb:typesafeEnumClass name="MyEnumType"/> 
        </jaxb:bindings> 
    </jaxb:bindings> 
</jaxb:bindings> 

The generated class (the relevant part):

/**
 * <p>Java class for null.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * <p>
 * <pre>
 * &lt;simpleType>
 *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
 *     &lt;enumeration value="SHIPPED"/>
 *     &lt;enumeration value="PENDING"/>
 *   &lt;/restriction>
 * &lt;/simpleType>
 * </pre>
 * 
 */
@XmlType(name = "")
@XmlEnum
public enum MyEnumType {

    SHIPPED,
    PENDING;

    public String value() {
        return name();
    }

    public static ShipmentStatusType.MyEnumType fromValue(String v) {
        return valueOf(v);
    }

}
Community
  • 1
  • 1
Petru Gardea
  • 21,373
  • 2
  • 50
  • 62
  • Nope, i am already workign the way "SO" was suggested to do. but it didn't work – Em Ae Aug 13 '12 at 21:25
  • 1
    @EmAe, I beg to differ. It means you didn't follow the idea. The thing is you don't have to modify the XSD and you should avoid solutions that asks you to do it, unless the tool can't really handle it. – Petru Gardea Aug 14 '12 at 01:44