No standard is perfect – in fact the DDI specification made this quite clear through the inclusion of the ‘Note‘ object to support extensions and to hold additional information. However, DDI Notes are usually seen as a mechanism of last resort for describing structured content as they are by their very nature _un_structured. There is however an intermediate solution between the implementation of Notes and leaving out vital information or using less optimal modeling to document everything. The way that I’ll demonstrate here is through the use of XML Schema substitution groups.

From the XML Schema Documentation on substitution groups:

XML Schema provides a mechanism, called substitution groups, that allows elements to be substituted for other elements. More specifically, elements can be assigned to a special group of elements that are said to be substitutable for a particular named element called the head element.

In essense, this allows for a schema designer to specific what classes of element can validly exist within an XML tree, before designing more complex child elements. Similarly, it allows for extensibility by third-party designers.

Within DDI Lifecycle there are a number of Substitution groups that can support these kinds of extensions.

For example, the ControlConstruct and ControlConstructScheme are used in this manner to support the inclusion of complex questionnaire logic.

<xs:complexType name="ControlConstructSchemeType">
    <xs:annotation>
        <xs:documentation>A set of control constructs maintained by an agency, and used in the instrument. </xs:documentation>
    </xs:annotation>
    <xs:complexContent>
        <xs:extension base="r:MaintainableType">
            <xs:sequence>
        <!-- Elements removed -->
                <xs:element ref="ControlConstruct" maxOccurs="unbounded">
            <!-- Elements removed -->
                </xs:element>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>
<xs:element name="ControlConstruct" type="ControlConstructType" abstract="true">
    <!-- Elements removed -->
</xs:element>
<xs:element name="IfThenElse" type="IfThenElseType" substitutionGroup="ControlConstruct"/>

Here the ControlConstructScheme declares the existance of a ControlConstruct child element, while the ControlConstruct acts as the Head Element for the substitution group by declaring it to be an abstract, which supports the declaration of the IfThenElse element as a part of this substitution group.

To extend this we can create a new element, and declare it as an extension of the ControlConstruct, to support a new metadata object. A trivial example is below:

<xs:element name="Foo" type="FooType" substitutionGroup="d:ControlConstruct"/>
<xs:complexType name="FooType">
    <xs:complexContent>
        <xs:extension base="d:ControlConstructType"/>
    </xs:complexContent>
</xs:complexType>

Here the Foo Element is defined as a part of the ControlConstruct group, of the complex FooType, which has ComplexContent based on the ControlConstructType as defined in the head element. Provided that the XSD that defined this new element was included correctly within the final DDI Instance, this would be valid DDI 3.1 XML. This means that the following fragment with the correct imported schemas would validate as DDI:

<d:ControlConstructScheme id="FooBar">
    <sqdx:Foo id="Bar"/>
</d:ControlConstructScheme>

Now, lets look at this in practice. The ConditionalText element in DDI is used to document the existence of dynamic text in a survey instrument – be it as part of a question, statement or instruction. A conditional text exists as a part of the substitution group Text in the DataCollection Module. One issue with this element as it exists, is although it defines how it should display the dynamic text, there is no declaration of what the default text may be, or what to display in a static environment. We can however, improve this through the creation of an extension of this using the above techniques, as shown below.

<xs:element name="ExtendedConditionalText" type="ExtendedConditionalTextType" substitutionGroup="d:Text"/>
<xs:complexType name="ExtendedConditionalTextType">
    <xs:annotation>
        <xs:documentation>Text which has a changeable value, based on a condition expressed in Code. This is an extension of the standard DDI ConditionalText in the DataCollection Module, that provides support for default values for conditional text and text for static environments.</xs:documentation>
    </xs:annotation>
    <xs:complexContent>
        <xs:extension base="d:ConditionalTextType">
            <xs:sequence>
                <xs:element name="Default" type="r:StructuredStringType">
                    <xs:annotation>
                        <xs:documentation>The text to display prior to a dynamic change of text in an electronic environment.</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="Static" type="r:StructuredStringType">
                    <xs:annotation>
                        <xs:documentation>The text to display when dynamic changes of text are not available. For example, on paper forms or non-dynamic electronic forms - such as javascript less environments.</xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

In the above XML fragement, the ExtendedConditionalText is defined as an extension of the standard DDI ConditionalTextType, with additional elements defined as necessary.

<d:QuestionText>
    <d:LiteralText>
        <d:Text>You told me your dog likes to play fetch, what does </d:Text>
    </d:LiteralText>
    <sqdx:ExtendedConditionalText>
        <d:Expression>
            <r:Code programmingLanguage="Pseudocode">if sex == 'Male' {return 'he'} else if sex == 'Female' {return 'she'} else {return 'they'}</r:Code>
        </d:Expression>
        <sqdx:Default>...</sqdx:Default>
        <sqdx:Static>he/she</sqdx:Static>
    </sqdx:ExtendedConditionalText>
</d:QuestionText>

This use of XML Schema extensions then means, that not only is the data ctructure properly defined and sharable using standard XML technologies, it also provides an easy way for defining possible advancements for future versions of the standard.

So, where can these extensions be used in DDI – here is a list of some of the substitution groups that exist in DDI 3.1:

So where any of these substitution groups exist, a newly defined object could take their place. However, there are a few place where substitution groups would be advantages for future versions, the two main ones being a substitution group for Questions for incusion in QuestionSchemes, and as a replace for the reusable Code element to allow for more defined, system-independant and reusable logic within DDI.

Lastly, the example Schema for the above ExtendedConditionalText is available on Pastebin, with a more indepth example showing how a Case/Switch control construct could be created to define higher-order questionnaire logic.

There is also an example DDI instance on Pastebin that has concrete examples of all of the extensions listed.