The effects of cardinality inheritance <xs:extension> on the generated code

A base complex type can be extended, the concept is similar to that of inheritance in C#, C++, Java, Vb.Net etc. In this sample we define a base complex type 'BaseComplexType', and derive from it 2 other complex types 'DerivedComplexType1' & 'DerivedComplexType2'.
Finally we define an element 'UsingElement' that contains an instance of the element 'BaseComplexType'.

Note : According to the XSD standard, wherever we see a reference to the element 'BaseComplexType', we can use either 'DerivedComplexType1' or 'DerivedComplexType2'. This is also true in the generated code.

Sample XSD

 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
elementFormDefault
="qualified"
attributeFormDefault="unqualified">
    <xs:complexType name="BaseComplexType">
        <xs:sequence>
            <xs:element name="ChildOfBaseType" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="DerivedComplexType1">
        <xs:complexContent>
            <xs:extension base="BaseComplexType">
                <xs:sequence>
                    <xs:element name="ChildOfDerivedType1" type="xs:string"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="DerivedComplexType2">
        <xs:complexContent>
            <xs:extension base="BaseComplexType">
                <xs:sequence>
                    <xs:element name="ChildOfDerivedType2" type="xs:string"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:element name="UsingElement">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="BaseType" type="BaseComplexType"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

The Generated Code

As you can see a class is created for every element defined within the schema. In order to allow any element that extends BaseComplexType, to be used wherever BaseComplexType is referenced (i.e. in UsingElement) an interface has been created (IBaseComplexType). This is implemented by all classes capable of being used where BaseComplexType appears.

Sample Code

The Code below shows how the resulting classes can be used create an XML document.

 // create an instance of the class to load the XML file into 
ExtensionLib.UsingElement elm = new ExtensionLib.UsingElement();

//////////////////////////////////////
// Write Data into the new element
// Use the element DerivedComplexType2 in the base element
// UsingElement.BaseType where a BaseComplexType is exected
ExtensionLib.DerivedComplexType2 elmDerv2 = new ExtensionLib.DerivedComplexType2();
elmDerv2.ChildOfBaseType = "Data field From Base";
elmDerv2.ChildOfDerivedType2 = "Data field From Derived Class";
elm.BaseType = elmDerv2;

// Look at the XML we just created
Trace.WriteLine(elm.ToXml());

//////////////////////////////////////
// Read data from the element
// The object we get from elm.BaseType is exposed via
// an interface common to all the objects that can
// be used in its place (IBaseComplexType).
Trace.WriteLine("Data from the Base class - " + elm.BaseType.ChildOfBaseType);

// The actual object held in elm.BaseType can be either
// DerivedComplexType1, DerivedComplexType2 or BaseComplexType
// we need to use runtime type info to find out.
if (elm.BaseType is typeof(DerivedComplexType2))
{
    // now we know the type, we can cast it up accordingly
    ExtensionLib.DerivedComplexType2 elmDerv =(ExtensionLib.DerivedComplexType2)elm.BaseType;
    // and then make use of the properties defined in the derived class
    Trace.WriteLine("Data in DerivedComplexType2.ChildOfDerivedType2 class - " + elmDerv.ChildOfDerivedType2);
}

The output from the sample above

<?xml version="1.0"?> 

<!--Created by Liquid XML Data Binding Libraries (www.liquid-technologies.com) for simon-->
<UsingElement xmlns:Xs="http://www.w3.org/2001/XMLSchema-instance">
    <BaseType Xs:type="DerivedComplexType2">
        <ChildOfBaseType>Data field From Base</ChildOfBaseType>
        <ChildOfDerivedType2>Data field From Derived Class</ChildOfDerivedType2>
    </BaseType>
</UsingElement>