Handling Choice Elements in the BPM API Schemas

Some elements in the BPM API schemas use xsd:choice elements. In some programming environments (such as .NET in its default form), when you generate the services.cs file, choice elements are represented by a parent entity (in this case, Item) which can be cast to any of the types which the choice allows

For example, the .NET framework represents such elements as the first common parent of both types - typically object, with XmlElementAttribute attributes to serialize the type as an instance of the different types available in the choice.

This means that you will need to programmatically determine the correct type of the field at runtime to correctly handle an instance of the field.

For example, FieldType is a complexType that defines a single data field. It is returned as part of an openWorkItemresponse.workItemBody.dataModel element, to define the INPUT, OUTPUT and INOUT parameters that define the work item’s data model.

The definition contains an xsd:choice element that determines whether the field value is of type:

  • simpleSpec - a simple data type (such as an integer or string)
  • complexSpec - a business data type (derived from a Business Object Model class).

When you generate the services.cs file, the .NET Framework translates this part of the XML schema into the following code:

public partial class FieldType
{
.
.
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("complexSpec", typeof(FieldTypeComplexSpec), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)]
    [System.Xml.Serialization.XmlElementAttribute("simpleSpec", typeof(FieldTypeSimpleSpec), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)]
    public object Item
    {
        get
        {
            return this.itemField;
        }
        set
        {
            this.itemField = value;
        }
    }
.
.

The field is given the object type, but also carries two XmlElementAttribute attributes - one tells the serialization engine to serialize the type as a fieldTypeComplexSpec instance, the other to serialize the type as a fieldTypeSimpleSpec instance. This indicates that the field could be either a simple type or a complex type.

If you need to handle a piece of FieldType data in your code, at runtime you must programmatically determine whether the instance is of type fieldTypeComplexSpec or fieldTypeSimpleSpec. For example:

  • Use an if .. is condition to determine the object’s data type.
  • Explicitly cast the object to the correct data type before processing it.
    if (field.Item is FieldTypeSimpleSpec)
    {
       FieldTypeSimpleSpec item = (FieldTypeSimpleSpec)field.Item;
       // Process item as a piece of simple data
    }
    else
    {
       FieldTypeComplexSpec item = (FieldTypeComplexSpec)field.Item;
       // Process item as a piece of business data
    }