MinOccurs Attribute Binding Support
The .NET Framework provides partial binding support for the minOccurs attribute.
Only for the <element> element does Xsd.exe check the value of the minOccurs attribute, and only if the value of theattribute does not dictate an array field. Then, the value is interpreted (or produced) according to various factors, starting with whether the corresponding field has a reference or value type.
The minOccurs and maxOccurs attributes constrain how many times in succession the specified entity can appear in the corresponding position in an XML instance document.
These attributes appear only within complex type definitions. Therefore, for an <element> or <group> element, the element must be a local declaration or a reference to a global declaration, not the global declaration itself.
For binding XML Schema complex types with non-XML-specific classes, the .NET Framework does not provide a direct programming language equivalent to the minOccurs or maxOccurs attribute.
When generating source code from an XML Schema document, Xsd.exe ignores the minOccurs attribute applied to the <choice>, <sequence>, <group>, <all>, and <any> elements.
For the <element> element, Xsd.exe ignores the minOccurs attribute if the value of the maxOccurs attribute is greater than 1, or unbounded. In this case, the tool produces an array of the type corresponding to the XSD data type. Xsd.exe uses the value of the maxOccurs attribute to determine whether to produce a single instance or an array.
For the <element> element, Xsd.exe also ignores the minOccurs attribute if it is applied to a schema data type that converts to a .NET Framework reference type.
Only when all the following conditions are true does Xsd.exe utilize the value of the minOccurs attribute:
The <element> element is involved.
The maxOccurs attribute dictates a single instance.
The data type converts to a value type.
The tool then interprets the value as follows:
1 or more: Xsd.exe generates a public field. No XML-related attribute is applied, so the default System.Xml.Serialization.XmlElementAttribute is used.
0: Xsd.exe generates a public field. No XML-related attribute is applied, so the default XmlElementAttribute is used. In addition, Xsd.exe generates a public field of type bool whose name is the element field's name with Specified appended. For example, if the element field's name is startDate, the bool field's name becomes startDateSpecified. When serializing an object to XML, the XmlSerializer class checks the value of the bool field to determine whether to write the element. The bool field appears with a System.Xml.Serialization.XmlIgnoreAttribute to prevent it from being serialized by XmlSerializer.
More on array bindings. A loss of definition precision occurs when Xsd.exe ignores the minOccurs attribute in the case when the maxOccurs attribute value dictates an array binding. A reverse translation from the generated array to a new <element> declaration produces not the original minOccurs value but a value of 0, plus a maxOccurs value of unbounded.
To understand the type binding to an array, consider the difference between declaring an object of a certain type and assigning a value (literally a memory location in the stack or the heap) to that object. Start with the following XSD element:
<xsd:element minOccurs="5" maxOccurs="5" name="items" type="xsd:token" />
Manually writing code, you would not express the array size of five in the type declaration, which would be: public string items. Instead you would express the array size when assigning a value: items = new string.
The only kinds of source code Xsd.exe produces from an XML schema are type and field declarations and metadata that can be applied to types and fields as attributes. Assigning values to objects extends beyond that scope.
The place to enforce a value greater than 1 is by validating an XML document with the XmlValidatingReader class against an XML Schema document represented by the Schema Object Model (SOM). The SOM uses the XmlSchemaParticle.MinOccurs and XmlSchemaParticle.MinOccursString properties, both of which apply to all elements that can contain a minOccurs attribute.
For more information on how Xsd.exe handles occurrence constraints in different XML Schema definition language elements, see the maxOccurs attribute.
The minOccurs value that Xsd.exe produces when generating an XML Schema document from classes depends on the containing XML Schema definition language element being generated. The possible containing elements, along with their minOccurs behavior, are listed as follows:
<choice>: 1 if the choice represents a single object, 0 if the choice represents an array.
<sequence>: Not specified, reverting to the default 1.
<group>: Xsd.exe does not generate a <group> element from source.
<all>: Xsd.exe does not generate an <all> element from source.
<any>: 0 according to the rules explained for the <element> element. The <any> element is discussed further later in this topic.
<element>: Xsd.exe produces different values for minOccurs depending on whether a field or property is an array or single instance; whether a field or property has a value type or reference type; whether a value type has either a default value or an extra field saying whether a value has been specified; and whether a reference type is assigned an XML-related attribute with an IsNullable property set to true.
The IsNullable property is used by certain XML-related attribute classes. The property appears as follows:
If a class member's IsNullable property is set to true and an object has been set to a null reference (Nothing in Visual Basic), the XmlSerializer class generates an xsi:nil attribute with a value of true. (The prefix xsi is used for the XML Schema instance namespace, http://www.w3.org/2001/XMLSchema-instance).
The presence of xsi:nil="true" in an element within an instance document explicitly states that the element has no content, whether child elements or body text. See the xsi:nil attribute.
The IsNullable property corresponds to the nillable attribute in the XML Schema definition language. If, while generating XSD definitions from classes, Xsd.exe encounters a true value for a class or member's IsNullable property (and the type can be assigned a null reference), a nillable="true" setting is generated for the corresponding XSD <element> element. See the nillable attribute.
The rules shown in the following table determine the value of the minOccurs attribute corresponding to a class member that is a single instance. Arrays also follow these rules, with one exception, described later in this topic. The table is organized according to the relevant class member variations, along with the resulting minOccurs values:
Input class member
minOccurs value of output <element> element
Value type with a default value specified via a System.Component.DefaultValueAttribute.
0. In the <element> element, the default value is also specified via the default XML attribute.
Value type accompanied by a public bool field that uses the Specified naming convention described previously under Translating XSD to source.
Value type with no default value or accompanying boolean field.
Reference type with an XmlElement attribute's IsNullable property set to true.
1. In the <element> element, the nillable attribute is also set to true.
Reference type with IsNullable=false or no IsNullable setting.
Xsd.exe preserves these distinguishing features on a reverse translation from an XML Schema document to source code.
Note: If a default XML attribute appears with a minOccurs attribute set to 0—and the data type maps to a value type—only the DefaultValue attribute is generated. The accompanying boolean field is not. Also see the default attribute.
For instance, suppose the following element was encountered in the input source file:
<xsd:element name="birthdate" type="xsd:date" default="2002-03-04" minOccurs="0" />Xsd.exe would then produce: [System.Xml.Serialization.XmlElementAttribute(DataType="date")] [System.ComponentModel.DefaultValueAttribute(typeof(System.DateTime), "2002-03-04")] public System.DateTime birthdate = new System.DateTime(631507968000000000);
Array bindings. Xsd.exe always produces an <element> declaration of the following form for arrays.
<element minOccurs="0" maxOccurs="unbounded" />
This is true because array types are reference types. However, unlike with other reference types, this is true even if the following attribute declaration is applied to the array member:
When an XmlElement attribute, instead of the default XmlArrayAttribute, is applied to an array, the array elements appear in an instance document as children of the element that binds to the class. There is no extra element introduced strictly to serve as the array elements' parent. While Xsd.exe recognizes the IsNullable=true setting by producing an element with nillable="true", a minOccurs value of 0 is still generated and the array elements can still be absent.
If the default XmlArray attribute is applied, a schema data type, with a name that begins with ArrayOf, is created to represent the array's parent element. For more information on array bindings, see the maxOccurs attribute and Controlling XML Serialization Using Attributes.
The parent elements schema data type corresponds to a reference type and Xsd.exe treats it as such when generating a minOccurs value. That is, a minOccurs value of 1 is generated if the IsNullable property is set to true as follows:
Otherwise, a minOccurs value of 0 is generated.
<any> element. The reason Xsd.exe generates minOccurs="0" for an <any> element—regardless of whether a single object or an array is involved—is that the equivalent code construct is a reference type. That construct is a field of type System.Xml.XmlElement (or an array thereof), with an attribute System.Xml.Serialization.XmlAnyElementAttribute. An attribute declaration, [XmlElementAttribute(IsNullable=true)], could be applied to the XmlElement object or the array, but Xsd.exe does not interpret this usage as an <any> element with minOccurs="1".