This section provides a more detailed look at the nuts and bolts of going from an XSD to code. Part 1 - What is XML Data Binding? - an introduction to the technology. XML Data Binding - In More Detail As you have already seen using the code generated from a data binding tool can greatly reduce the amount & complexity of the code you have to write when dealing with XML. If you have a complex schema, and are not XSD experts the benefits are clear. Elements Examined A sequence describes an element, and defines that all child elements must appear (if mandatory) and they must appear in the correct order. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="ParentSeq"> <xs:complexType> <xs:sequence> <xs:element name="FirstChild" type="xs:string"/> <xs:element name="SecondChild" type="xs:string"/> <xs:element name="ThirdChild" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> Generated Code This is a UML representation of the generated code, note that there are 3 string properties (FirstChild, SecondChild & ThirdChild) corresponding with the child elements within ParentSeq. Sample Code - Creating an XML document using the generated classes Xml Created <?xml version="1.0"?><!--Created by Liquid XML Data Binding Libraries (www.liquid-technologies.com) for Liquid Technologies Ltd--> <ParentSeq xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"> <FirstChild>Some Data 1</FirstChild> <SecondChild>Some Data 2</SecondChild> <ThirdChild>Some Data 3</ThirdChild> </ParentSeq> Notes It does not matter the order in which the child elements are set they will appear in the output XML correctly. A choice describes an element, and defines that only one of the child elements can appear. Sample XSD <?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="ParentSeq"> <xs:complexType> <xs:choice> <xs:element name="FirstChild" type="xs:string"/> <xs:element name="SecondChild" type="xs:string"/> <xs:element name="ThirdChild" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element> </xs:schema> Generated Code This is a UML representation of the generated code, note that there are 3 string properties (FirstChild, SecondChild & ThirdChild) corresponding with the child elements within ParentSeq. There are also 3 other properties IsValidFirstChild, IsValidSecondChild &IsValid ThirdChild, these indicate whether the corresponding property contains a valid value. The property ChoiceSelectedElement, indicates which of the 3 elements is selected at any given time. If one element is selected (i.e. FirstChild contains a value), and then another is given a value (say SecondChild is set to "Some Text"), then FirstChild will become invalid (IsValidFirstChild will return false, and reading from FirstChild with raise an exception), and ChoiceSelectedElement will reference SecondChild. Sample Code - reading an XML Document from a file
Notes If more than one child element is selected in the XML then the FromXmlFile will raise an exception. We.ve now covered how the basic constructs (all/sequence/choice) are represented. However all the child items used have all been of type string. Sample XSD <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="RootElm"> <xs:complexType> <xs:sequence> <xs:element name="StringType" type="xs:string"/> <xs:element name="intType" type="xs:int"/> <xs:element name="ComplexType"> <xs:complexType> <xs:sequence> <xs:element name="DateType" type="xs:dateTime"/> <xs:element name="Base64Type" type="xs:base64Binary"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> Classes Created
Here 2 classes have been created RootElm & ComplexType. Sample Code - creating an XML document // create an instance of the class to load the XML file into TypesLib.RootElm elm = new TypesLib.RootElm(); // set data into the element elm.StringType = "Test String value"; elm.IntType = 5; // and the child element elm.ComplexType.DateType.SetDateTime(2004, 4, 26, 10, 41, 35); elm.ComplexType.Base64Type.SetData("075BCD15", BinaryData.Encoding.Hex); // Lets look at the XML we produced. Trace.WriteLine(elm.ToXml()); XML Produced <?xml version="1.0"?> <!--Created by Liquid XML Data Binding Libraries (www.liquid-technologies.com) for Liquid Technologies Ltd--> <RootElm xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"> <StringType>Test String value</StringType> <intType>5</intType> <ComplexType> <DateType>2004-04-26T10:41:35</DateType> <Base64Type>cLXcUQ==</Base64Type> </ComplexType> </RootElm> Notes If the ComplexType held within the RootElm was optional, then you would have to create and assign an object to elm.ComplexType before using it (see next item). In this sample, the sequence contains a number of child elements. The child elements all have different cardinality (changed by setting the minOccurs and maxOccurs attributes, the default for both is 1). The generator deals with these flags in 3 different ways. Mandatory - minOccurs=1 and maxOccurs=1 Optional - minOccurs=0 and maxOccurs=1 Collection - minOccurs=n and maxOccurs= >1 If the child element is another complex element (i.e. represented as new class in the generated code), then a get accessor is provided. This returns an object that represents a collection of the complex elements. Sample XSD <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="Cardinality"> <xs:complexType> <xs:sequence> <xs:element name="MandatoryChild" type="xs:string"/> <xs:element name="OptionalChild" type="xs:string" minOccurs="0"/> <xs:element name="CollectionChild" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> Generated Code As you can see there are 3 main properties within the class (MandatoryChild, OptionalChild & CollectionChild). Xml Created <?xml version="1.0"?> <!--Created by Liquid XML Data Binding Libraries (www.liquid-technologies.com) for Liquid Technologies Ltd--> <Cardinality xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"> <MandatoryChild>Some value</MandatoryChild> <CollectionChild>First item in collection</CollectionChild> <CollectionChild>Second item in collection</CollectionChild> </Cardinality> Notes We use the IsValidOptionalChild property to determine if the OptionalChild element was present in the XML. Extension A base complex type can be extended, the concept is similar to that of inheritance in C# C++ Java etc. In this sample we define a base complex type 'BaseComplexType', and derive from it 2 other complex types 'DerivedComplexType1' & 'DerivedComplexType2'. 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>
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.
// create an instance of the class to load the XML file into Xml Created <?xml version="1.0"?> <!--Created by Liquid XML Data Binding Libraries (www.liquid-technologies.com) for Liquid Technologies Ltd--> <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> Notes |