Xsi:nil Attribute Binding Support
The .NET Framework provides partial binding support for the xsi:nil attribute.
The XmlSerializer class equates an xsi:nil="true"
attribute value with a null reference assigned to a reference type or to a nullable value type. XmlSerializer throws an exception when it attempts to deserialize an instance of a non-nullable value type if the nil attribute is set to true
. (For more information about nullable types, see Nullable Types (C# Programming Guide)).
Explanation
The nil attribute is defined in the XML Schema instance namespace, http://www.w3.org/2001/XMLSchema-instance (commonly associated with the prefix xsi), and applies only to XML instance documents, not XML Schema documents. A value of true
for the xsi:nil attribute in an XML element explicitly specifies that the element has no content, whether child elements or body text.
A nil attribute can only validly appear in an XML element whose XSD declaration contains a nillable attribute set to true
. See the nillable attribute for how the .NET Framework determines whether a nillable="true"
setting applies to an XML element corresponding to an object or member.
The XmlSerializer class equates a true
value for the nil attribute with a null reference (Nothing in Visual Basic), performing the following run-time conversions:
When deserializing an XML document into objects: If the XmlSerializer class encounters an XML element that specifies
xsi:nil="true"
, it assigns a null reference (if applicable) to the corresponding object.When serializing objects into an XML document: If the XmlSerializer class encounters a null reference for an object corresponding to an XML element, it either generates an element that specifies
xsi:nil="true"
or leaves the element out entirely, depending on whether anillable="true"
setting applies.
The nil attribute and non-nullable value types
Since a non-nullable value type can never be set to a null reference, when a class member of such a type is mapped to an XML element declaration, the XmlSerializer class during serialization has no reason to output the xsi:nil attribute for a corresponding instance element.
The XmlSerializer class is unable to deserialize an XML element whose data type maps to a non-nullable value type and whose nil attribute has been set to true
. When deserializing an XML document into objects, if the XmlSerializer class encounters such an element, it issues a System.FormatException: "Input string was not in a correct format." This situation can arise if the XML document has been created by an XML Schema implementation that allows the nil attribute to appear in instances of schema data types that the .NET Framework binds to non-nullable value types.
The nil attribute and other attributes
The XML Schema specification allows other XML attributes to appear in an element whose xsi:nil attribute has been set to true
. Since the only time the XmlSerializer class sets the nil attribute to true
is when the corresponding object is assigned a null reference, any object fields representing XML attributes (via an attribute of type System.Xml.Serialization.XmlAttributeAttribute) cannot even exist in memory at that point.
Therefore, the XmlSerializer class treats additional attributes as follows:
When serializing objects into an XML document: If the XmlSerializer class encounters a null reference for an object corresponding to an XML element for which the nil attribute should be specified, it omits any other attributes.
When deserializing an XML document into objects: If the XmlSerializer class encounters an XML element that specifies
xsi:nil="true"
, it assigns a null reference to the corresponding object and ignores any other attributes. This situation can arise if the XML document has been created by an XML Schema implementation that allows other attributes to appear along withxsi:nil="true"
—effectively not binding a nil value oftrue
to a null object reference.
Invalid nil attribute for string types
Consider the following <element> declaration with the default false
value explicitly specified for the nillable attribute:
<xsd:element name="key" type="xsd:string" nillable="false" />
This element would bind to the following class member (the default false
value is explicitly specified for the IsNullable property):
[System.Xml.Serialization.XmlElementAttribute(IsNullable=false)]
public string key;
Suppose that an XML instance document contains the following element that is intended to conform to the preceding <element> declaration:
<key xsi:nil="true"/>
The XmlValidatingReader class would recognize this element as invalid because it uses a nil instance attribute when the nillable definition attribute's value is false
. The XmlSerializer class, however, would not throw an exception while deserializing this element; instead, it would set the corresponding key
field's value to an empty string, expressed ""
.
Possible containing elements: any instance element