Choice

XML Schema defines the Choice content model as an element which allows to select one of it's children for an instance document. The child of a Choice element can be an XML element or another content model such as sequence. Java has no equivalent to the XML Choice content model.

We have decided to model the Choice in the following way in Java - Assume we have a Java class with a set of properties.

  1. We define one special property (the "choice discriminator") which must be an enumeration. The value of this special property selects which of the choice options we have in the instance document. Each enumeration constant is considered one "choice option".

    The "choice discriminator" property is mapped using the @MOChoiceDiscriminator annotation.

  2. We select which of the other properties is associated with which choice option. One property can be associated with multiple choice options, or with none. A property that is not associated with any of the choice options is handled as a normal property (not part of the choice content model). A property that is associated with one or more choice options will appear under each choice option it is associated with (in the XML schema).

    Each property associated with the choice structure is mapped with the @MOPropertyChoice annotation (in addition to any other annotations, including @MOProperty ).

An example:

we define a choice discriminator property using the

@MOChoiceDiscriminator(xmlOrder = 2)
public CustomerType getCustomerType() {...}
...
public enum CustomerType {employeeCustomer, personCustomer}

To define a property that is associated with one the choice option (the employeeCustomer option) we use

@MOProperty(xmlOrder = 2, xmlName = "employee", xmlOptional = false)
@MOPropertyChoice(discriminator = "customerType", choiceOptions = {"employeeCustomer"})
public Employee getEmployee() {...}

To define a property that is associated with multiple choice options we use

@MOProperty(xmlOrder = 4, xmlName = "address", xmlOptional = false)
@MOPropertyChoice(discriminator = "customerType", choiceOptions = {"employeeCustomer","personCustomer"})
public Address getEmployeeAddress() {...}

The complete source code for this example can be found here The XML Schema generated for this mapping is then

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:ns3="http://example.abra.com/enumsAndValidations/customer"
    xmlns:ex3="http://example.abra.com/enumsAndValidations/employee"
    xmlns:ex7="http://example.abra.com/dependentObjectsProperty"
    targetNamespace="http://example.abra.com/enumsAndValidations/customer"
    elementFormDefault="qualified" attributeFormDefault="unqualified">
  <xs:import namespace="http://example.abra.com/enumsAndValidations/employee" schemaLocation="com.abra.example.enumsAndValidations.employee.xsd"/>
  <xs:import namespace="http://example.abra.com/dependentObjectsProperty" schemaLocation="com.abra.example.dependentObjectsProperty.xsd"/>
  <xs:element name="Customer">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="name" type="xs:string"/>
        <xs:choice>
          <xs:element name="employeeCustomer">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="employee" type="ex3:EmployeeType"/>
                <xs:element name="address" type="ex7:AddressType"/>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
          <xs:element name="personCustomer">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="person" type="ex7:PersonType"/>
                <xs:element name="address" type="ex7:AddressType"/>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>