Overview
The sample shows how the minOccurs and maxOccurs attributes are dealt with. The sample contains a sequence which 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) |
|
If the child element is a primitive (string, short time etc) then a get & set accessor is provided. The value held must always contain a valid (non null) value.
If the child element is another complex element, then a get & set accessor is provided. The child element will be represented as as a class (which will also be generated). An instance of the child class will be created along with the parent object, so does not need explicitly setting before it can be used. This will always return a valid object (you can not set it to null).
Optional (minOccurs=0 and maxOccurs=1)
If the child element is a primitive (string, short time etc) then a get & set and IsValid accessor is provided. While IsValid is true the value held must always contain a valid (non null) value. If IsValid is set to false then the get accessor will fail if called, and no child element is created in the XML.
If the child element is another complex element (i.e. represented as a generated class), then a get & set accessor is provided. This will initially be null. If the child element is required in the XML, then a new child object must be created (new XXX()), and assigned to the property, it can be removed by setting the value to null.
Collection (minOccurs=n and maxOccurs= >1)
If the child element is a primitive (string, short time etc) then a get accessor is provided. The object returned from the get operator is a collection of primitive types, if the collection is empty then no items appear in the XML.
If the child element is another complex element (i.e. represented as a generated class), then a get accessor is provided. This returns an object that represents a strongly typed 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>

The Generated Code
As you can see there are 3 main properties within the class (MandatoryChild, OptionalChild & CollectionChild).
The OptionalChild can be present in the XML or missing, because the item is a primitive, and can not be set to null (at least not in all languages) there is an additional property IsValidOptionalChild. This is a boolean field indicating if the value of OptionalChild is valid. If IsValidOptionalChild is false, and an attempt is made to read OptionalChild, then an exception is raised. IsValidOptionalChild can also be set to false in order to remove the element from the XML output.
The MandatoryChild has to be present, and so there is no need for an IsValidMandatoryChild property. Attempts to set a null value into MandatoryChild will cause an exception to be raised.
The CollectionChild references a collection (in this case a collection of strings), the property will never be null, however the collection may be empty.

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
CardinalityLib.Cardinality elm = new CardinalityLib.Cardinality();
// Write data into the element
elm.MandatoryChild = "Some value";
// set some data into the optional element
elm.OptionalChild = "Some other data";
// if we change our mind we can remove this element from the output
elm.IsValidOptionalChild = false;
// The collection element contains a child collection (the
// collection is always populated)
elm.CollectionChild.Add("First item in collection");
elm.CollectionChild.Add("Second item in collection");
// Lets look at the XML we've just created
Trace.WriteLine(elm.ToXml());
// Reading from the element
Trace.Write("Mandatory element contains value - " + elm.MandatoryChild);
if (elm.IsValidOptionalChild == true)
Trace.Write("Optional element present. Value - " + elm.OptionalChild);
else
Trace.Write("The optional element is not present");
Trace.Write("Child elements in the Collection element");
foreach(string val in elm.CollectionChild)
Trace.Write(" value - " + val);
The output from the sample above
<?xml version="1.0"?>
<!--Created by Liquid XML Data Binding Libraries (www.liquid-technologies.com) for simon-->
<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.
|