Liquid XML Data Binder 2020
Liquid XML Objects (C#, Visual Basic .Net) / Using the Generated Code / XML Schema Handling / xs:complexType
In This Topic
    xs:complexType
    In This Topic

     Sample Schema

    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 XSD explained

    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.

    Generated Code

    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; }
            }
        }
    
    The Lx... attributes, qualifying namespaces and comments have been removed for clarity.

    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.

     

    Writing Sample Code 

    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);
    

    Sample Output

    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&amp;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>
    

    Reading Sample Code

    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
    

     

     

    See Also