CHOICE

Generated C++ Get/Set Methods

The XSD CHOICE type <xsd:choice> is a complex type consisting of a series of element definitions from which one may be selected to include in a message instance. It is converted into a C or C++ structured type containing an integer for the choice tag value (t) followed by a union (u) of all of the equivalent types that make up the CHOICE elements.

The tag value is simply a sequential number starting at one for each alternative in the CHOICE. For C, a #define constant is generated for each of these values. The format of this constant is T_TypeName_elemName where TypeName is the name of the XSD complexType and elemName is the name of the CHOICE alternative. For C++, an enumerated type is added to the class with enumerations of the form T_elemName.

The union of choice alternatives is made of the equivalent C or C++ type definition followed by the element name for each of the elements. The rules for element generation are essentially the same as was described for SEQUENCE above. Constructed types or elements that map to C structured types are pulled out and temporary types are created. Names for elements that are not named (for an inline content group for example) names are automatically generated when needed.

The general mapping is as follows:

XSD type:

   <xsd:complexType name=”TypeName”>
      <xsd:choice>
         <xsd:element name=”elem1” type=”Type1”/>
         <xsd:element name=”elem2” type=”Type2”/>
         ...
         <xsd:element name=”elemN” type=”TypeN”/>
      </xsd:choice>
   </xsd:complexType>

Generated C code:

   /* choice tag constants */
   #define T_TypeName_elem1 1
   #define T_TypeName_elem2 2
   ...
   #define T_TypeName_elemN N

   typedef struct TypeName {
      OSUINT16 t;
      union {
         /* t = 1 */
         Type1 elem1;
         /* t = 2 */
         Type1 elem2;
         ...
         /* t = N */
         TypeN elemN;
      } u;
   } TypeName;

Generated C++ code:

   class TypeName : public OSXSDComplexType {
   public:
      enum {
         T_elem1 1
         T_elem2 2
         ...
         T_elemN N
      };
      OSUINT16 t;
      union {
         /* t = 1 */
         Type1 elem1;
         /* t = 2 */
         Type1 elem2;
         ...
         /* t = N */
         TypeN elemN;
      } u;
      ...
   } ;

In most cases, the generated elements within the C union construct will be pointers to dynamic variables rather than inline static value references. The only exception to this rule is if the referenced type of the element is a simple, atomic type such as an integer. The reason for using pointers is to keep the size of the structures small (otherwise, it will be sized to fit the largest possible variable size even if that alternative is not being used) and to avoid problems with C++ constructor invocations if C++ types with constructors are referenced within the union.

Choice elements cannot be optional or repeating. Instead, the entire choice group itself could be labeled as optional or repeating within another construct (a sequence, for example). It is possible to nest other XSD sequence or choice content model groups within another choice. The rules for handling this are as described in the handling of nested types for sequence above.