Partager via


Default Attribute Binding Support

The .NET Framework provides partial binding support for the default attribute.

The Xsd.exe tool equates a default element or attribute value with a System.ComponentModel.DefaultValueAttribute applied to a generated field; the field is also statically initialized to the default value.

Explanation

The default attribute, which can appear in an <element> or <attribute> declaration, provides a default value to be used if the element is empty or the attribute is not present when an instance document is received.

For attributes, a default value is relevant only if an attribute is optional (the use attribute has the default value optional). When an attribute is specified, it has to be specified with a value.

For elements, a default value is used only if the element appears in an instance document without any content. If the element doesn't appear at all, it doesn't get filled in.

When generating source code from an XML Schema document, Xsd.exe takes each field corresponding to an element or attribute with a default value and applies a System.ComponentModel.DefaultValueAttribute, passing the default value as an argument. In addition, Xsd.exe statically initializes the field to the default value, as in the following example:

[System.ComponentModel.DefaultValueAttribute(-1)]
public int age = -1;

The default attribute will be ignored on arrays (elements with maxOccurs greater than 1).

Binding support by data type

According to the XML Schema, the default attribute value must be a simple type. For almost all simple types, Xsd.exe preserves the default value when it performs a round-trip translation from XML schema to classes and back to a new XML Schema document.

An exception is elements or attributes of type xsd:base64Binary or xsd:hexBinary. A DefaultValue attribute is not applied to the corresponding System.Byte field created.

Another exception is attributes of list types. The <list> construct is used to define a simple type whose possible values are a white-space delimited series of values from another simple type. (Xsd.exe does not generate source code for elements of list types.) For lists, Xsd.exe creates an array of the constituent type but it converts the default value into an instance of the constituent type, not an array.

Consider the following input <attribute> declaration:

<xsd:attribute name="siblings" default="unknown">
  <xsd:simpleType>
    <xsd:list itemType="xsd:string"/>
  </xsd:simpleType>
</xsd:attribute>

For this declaration, the following source code is generated:

[System.Xml.Serialization.XmlAttributeAttribute()]
[System.ComponentModel.DefaultValueAttribute("unknown")]
public string[] siblings = "unknown";

This source fails to compile because a String object cannot be implicitly typecast as an array of String objects. The same error arises for lists of any simple type, including enumeration types.

Effect on minOccurs attribute for element-binding value types

Suppose a class member has a .NET Framework value type and maps to an XML element (via the default XmlElementAttribute). If Xsd.exe encounters a DefaultValue attribute applied to such a member when generating an XSD document from classes, it produces a value of 0 for the <element> element's minOccurs attribute. This indicates that the element does not need to appear in a valid XML instance document.

Combination with use="optional" for attributes

Suppose an <attribute> declaration contains a use attribute with a value of optional, which is also the default. When generating source code from an XSD document, Xsd.exe interprets this value in combination with whether the default attribute has been specified. The two possible interpretations are as follows:

  • default specified: Xsd.exe generates a public field with an XmlAttributeAttribute plus a DefaultValueAttribute specifying the default value.

  • no default specified: Xsd.exe generates a public field with an XmlAttributeAttribute. In addition, for value types, it generates a public field of type bool whose name is the attribute field's name with Specified appended. For example, if the attribute 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 optional attribute. The bool field appears with a System.Xml.Serialization.XmlIgnoreAttribute to prevent it from being serialized by XmlSerializer.

Example

Input XML Schema document:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            targetNamespace="http://example.org/" xmlns="http://example.org/" elementFormDefault="qualified">
    <xsd:element name="FamilyDog" type="FamilyDogType"/>

    <xsd:complexType name="FamilyDogType">
        <xsd:sequence>
            <xsd:element name="name" type="xsd:stringo" default="Spot"/>
            <xsd:element name="birthdate" type="xsd:date" default="2002-03-04"/>
        </xsd:sequence>
        <xsd:attribute name="gender" type="GenderType" default="UNKNOWN"/>
        <xsd:attribute name="fixed" type="xsd:boolean" default="false"/>
        <xsd:attribute name="breed" type="xsd:string" default="Swedish Vallhund"/>
    </xsd:complexType>
    
    <xsd:simpleType name="GenderType">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="FEMALE" />
            <xsd:enumeration value="MALE" />
            <xsd:enumeration value="UNKNOWN" />
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

C# classes generated from the preceding XML Schema document:

[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
[System.Xml.Serialization.XmlRootAttribute("FamilyDog", Namespace="http://example.org/", IsNullable=false)]
public class FamilyDogType {
        
    [System.ComponentModel.DefaultValueAttribute("Spot")]
    public string name = "Spot";
        
    [System.Xml.Serialization.XmlElementAttribute(DataType="date")]
    [System.ComponentModel.DefaultValueAttribute(typeof(System.DateTime), "2002-03-04")]
    public System.DateTime birthdate = new System.DateTime(631507968000000000);
        
    [System.Xml.Serialization.XmlAttributeAttribute()]
    [System.ComponentModel.DefaultValueAttribute(GenderType.UNKNOWN)]
    public GenderType gender = GenderType.UNKNOWN;
        
    [System.Xml.Serialization.XmlAttributeAttribute()]
    [System.ComponentModel.DefaultValueAttribute(false)]
    public bool @fixed = false;
        
    [System.Xml.Serialization.XmlAttributeAttribute()]
    [System.ComponentModel.DefaultValueAttribute("Swedish Vallhund")]
    public string breed = "Swedish Vallhund";
}
    
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
public enum GenderType {        
    FEMALE,        
    MALE,
    UNKNOWN,
}

The XML Schema document generated from an assembly compiled from the preceding C# source code is effectively the same as the original XML schema from which the C# source was generated.

Possible containing elements: <attribute>, <element>

See Also

Reference

XmlSchemaAttribute.DefaultValue
XmlSchemaElement.DefaultValue