Consider the following schema, Root must contain the child nodes A,B,C and 0-n D's.
The child elements must appear in the order show.

| ComplexTypeSample.xsd |
Copy Code
|
|---|---|
<?xml version="1.0" encoding="utf-8" ?> <!--Created with Liquid Studio (https://www.liquid-technologies.com)--> <xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Order"> <xs:complexType> <xs:sequence> <xs:element name="CustomerID" type="xs:int" /> <xs:element name="BillingAddress" type="AddressType" /> <xs:element name="ShippingAddress" type="AddressType" /> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType abstract="true" name="AddressType"> <xs:sequence> <xs:element name="Line1" type="xs:string" /> <xs:element name="Line2" type="xs:string" minOccurs="0" /> <xs:element name="Town" type="xs:string" /> </xs:sequence> <xs:attribute name="Name" type="xs:string" /> </xs:complexType> <xs:complexType name="UKAddressType"> <xs:complexContent> <xs:extension base="AddressType"> <xs:sequence> <xs:element name="County" type="xs:string" /> <xs:element name="Postcode" type="xs:string" /> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name="USAddressType"> <xs:complexContent> <xs:extension base="AddressType"> <xs:sequence> <xs:element name="State" type="xs:string" /> <xs:element name="Zipcode" type="xs:string" /> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> </xs:schema> |
|
The xs:element Order has 2 child xs:elements BillingAddress and ShippingAddress, which are both references to AddressType. This means that BillingAddress and ShippingAddress can contain content defined in any xs:complexType based on AddressType (i.e. AddressType, UsAddressType or UKAddressType). However because AddressType is marked as abstract, it can't be instantiated, so the content must be defined by UsAddressType or UKAddressType.
The following code is generated for the schema ComplexTypeSample.xsd.
| Generated Code |
Copy Code
|
|---|---|
public abstract partial class AddressTypeCt
{
public System.String Name { get; set; }
public AddressTypeSeq Seq { get; set; } = new AddressTypeSeq();
public partial class AddressTypeSeq
{
public System.String Line1 { get; set; } = "";
public System.String Line2 { get; set; }
public System.String Town { get; set; } = "";
}
}
public partial class UKAddressTypeCt : AddressTypeCt
{
public UKAddressTypeSeq Seq1 { get; set; } = new UKAddressTypeSeq();
public partial class UKAddressTypeSeq
{
public System.String County { get; set; } = "";
public System.String Postcode { get; set; } = "";
}
}
public partial class USAddressTypeCt : AddressTypeCt
{
public USAddressTypeSeq Seq1 { get; set; } = new USAddressTypeSeq();
public partial class USAddressTypeSeq
{
public System.String State { get; set; } = "";
public System.String Zipcode { get; set; } = "";
}
}
public partial class OrderElm
{
public OrderSeq Seq { get; set; } = new OrderSeq();
public partial class OrderSeq
{
public System.Int32 CustomerID { get; set; }
public AddressTypeCt BillingAddress { get; set; }
public AddressTypeCt ShippingAddress { get; set; }
}
}
|
|
A class is created for each root xs:complexType within the XSD. The mapping between the XSD and generated code is quite straightforward when you look at the graphical view of the XSD.
Notice that the UKAddressTypeCt ends up with its own xs:sequence which is named Seq1.
Generating Seq and Seq1 may seem unnecessary, but the compositor in UKAddressType could be different (i.e. a xs:choice) or have different cardinality to that of the xs:seqeunce in the base AddressType type. Furthermore structured as it is changes to the schema have fewer ripples in the generated code, meaning less re-work if the schema changes.

We can use the following code to build an instance of the Order Element
| Sample Code |
Copy Code
|
|---|---|
LxSerializer<OrderElm> serializer = new LxSerializer<OrderElm>(); OrderElm order = new OrderElm(); order.Seq.CustomerID = 3127; UKAddressTypeCt ukAddress = new Ns.UKAddressTypeCt(); ukAddress.Name = "Acme Corp Admin"; ukAddress.Seq.Line1 = "Office 3a"; ukAddress.Seq.Line2 = "5 The Headrow"; ukAddress.Seq.Town = "Leeds"; ukAddress.Seq1.County = "West Yorkshire"; ukAddress.Seq1.Postcode = "LS5 8HP"; order.Seq.BillingAddress = ukAddress; USAddressTypeCt usAddress = new Ns.USAddressTypeCt(); usAddress.Name = "Acme Corp R&D"; usAddress.Seq.Line1 = "1630 Revello"; usAddress.Seq.Town = "Sunnydale"; usAddress.Seq1.State = "CA"; usAddress.Seq1.Zipcode = "56482"; order.Seq.ShippingAddress = usAddress; serializer.Serialize(@"..\..\Order_Output.xml", order); |
|
| ComplexType_Output.xml |
Copy Code
|
|---|---|
<?xml version="1.0" encoding="utf-8"?> <Order> <CustomerID>3127</CustomerID> <BillingAddress p2:type="UKAddressType" Name="Acme Corp Admin" xmlns:p2="http://www.w3.org/2001/XMLSchema-instance"> <Line1>Office 3a</Line1> <Line2>5 The Headrow</Line2> <Town>Leeds</Town> <County>West Yorkshire</County> <Postcode>LS5 8HP</Postcode> </BillingAddress> <ShippingAddress p2:type="USAddressType" Name="Acme Corp R&D" xmlns:p2="http://www.w3.org/2001/XMLSchema-instance"> <Line1>1630 Revello</Line1> <Town>Sunnydale</Town> <State>CA</State> <Zipcode>56482</Zipcode> </ShippingAddress> </Order> |
|
The following code will read back in the files created above.
| Sample Code |
Copy Code
|
|---|---|
LxSerializer<OrderElm> serializer = new LxSerializer<OrderElm>(); OrderElm order = serializer.Deserialize(@"..\..\Order_Output.xml"); Console.WriteLine($"Order"); Console.WriteLine($" Customer ID : {order.Seq.CustomerID}"); Console.WriteLine($" Billing Address"); WriteAddress(order.Seq.BillingAddress); Console.WriteLine($" Shipping Address"); WriteAddress(order.Seq.ShippingAddress); |
|
When the valid XML file ComplexType_Output.xml is read and produces an object model identical to the one serialized out in the code above.
| Console Output |
Copy Code
|
|---|---|
Order
Customer ID : 3127
Billing Address
Name : Acme Corp Admin
Line 1 : Office 3a
Line 2 : 5 The Headrow
Town : Leeds
County : West Yorkshire
Postcode : LS5 8HP
Shipping Address
Name : Acme Corp R&D
Line 1 : 1630 Revello
Town : Sunnydale
State : CA
Zipcode : 56482
|
|