ComplexContent

The XSD ComplexContent type <xsd:complexContent> is used to create a modified version of a base type through extension or restriction mechanisms. It is similar in concept to creating derived types in Java or C++. ComplexContent is handled differently depending on whether C or C++ code is being generated. For C, the type is converted into a C structured type containing a base element (_base) and, optionally, an extensions element (_ext) and additional attribute elements. The extension element will only appear if the extension mechanism is used to add additional elements to an existing content model group (sequence, all, or choice).

In addition to the standard type that is generated to hold the type’s content, a special derivations type is also generated. This is generated in a separate file called <project>Derivations.h. This type is based on the base type of the derivation (i.e. the complexContent base element) and contains a union of all of the possible types that are derived from a given base. A reference to this type is used in all place where the base type is referenced. This makes it possible to handle type susstituition through the XML schema instance type attribute (xsi:type).

For C++, two distinct derivation models are supported - the extended and interface models.

The extended model is the model that was used in XBinder up to version 1.4. It is the model that would seem most natural in dealing with complexContent extensions. The generated base class contains all elements and attributes that were defined to exist in the base. The generated class for the complexContent type then inherits from this base class and adds whatever extended elements or attributes were added via the extension mechanism.

It was discovered, however, that this model could not cover all of the complexContent use cases in C++. In particular, certain types of complexContent restrictions caused problems, especially when the base class contained wildcards such as xsd:anyType or xsd:anyAttribute. The result was a very generic base type which was ill-suited for use with the special restriction cases. For this reason (and also for wishing to avoid the use of C++ multiple inheritance), the interface model was developed.

In the interface model, the inheritance mechanism is used with the generated derivations classes to make type substitution possible. All content items (elements and attributes) for a given complexContent type are aggregated in the generated class and then the derivations class is used as the base class. The derivations class is fully abstract - it contains no data items. It’s purpose is to act as an interface specification does in Java, it provides only a placeholder for the use of any of the concrete classes that can be used in the type.

XBinder 2.0 and higher nows supports both models. Either can be explicitly chosen by using the -derivModel command line switch or corresponding GUI option. If this option is not used, a model is automatically selected based on the schema being compiled. In general, if the schema being compiled contains no complexContent restrictions, the extended model will be chosen.