Are XML parsers/deserializers in general able to tell the difference between nillable elements explicitly set to null and optional elements that are left out?
Assume that we have the following complex type:
<complexType name="NiceType">
<sequence>
<element name="niceElem" nillable="true" type="int" minOccurs="0" />
</sequence>
</complexType>
Element explicitly set to null (example 1):
<niceType>
<niceElem xsi:nil="true"/>
</niceType>
Element omitted (example 2):
<niceType>
</niceType>
Would parsers in general, such as JAX-B implementations or .NET alikes such as the XML module of WCF, be able to tell the difference between example 1 and example 2 above? In other words, would you in an interoperable manner be able to combine both NULL representations - as in the example - in order to communicate different shades of NULL?
XML parsers (e.g.
XmlReader,XmlDocument,XDocument) don't treatxsi:nilspecially - you still see the element in the stream/document.XmlSerializerdoes handlexsi:nil: within that context it means the same thing as an omitted node; you can make WCF serialize usingXmlSerializerby marking yourDataContracts usingXmlSerializerFormatterAttribute.DataContractSerializerdoes use the attribute: however I am not sure what all the rules are for it to use them (one case is circular references) - it is much more likely to omit elements. I don't think you should passxsi:niltoDataContractSerializerunless it uses it in that case - asDataContractSerializeris designed around assumptions to improve de/serialization performance.From the spec it looks like it was originally designed to work like the JavaScript
nullandundefined- wherenull(xsi:nil) is a valid value andundefined(omitted) is the entire non-existence of a value; especially with complex types - you can provide the element but omit it's content (even if the content is required according to the schema).In general I would avoid it. It's non-intuitive - I don't think I have seen a REST/SOAP API out there that uses it (except InfoPath which uses it exclusively); most just use
null = undefined. The xmlns declaration and usage of it also eat a few extra valuable bytes.Bonus Marks: If you make an element optional and it isn't nullable (e.g.
xsd:int) the C# generator provides a<Name>Specifiedproperty - you can add your own properties like this. This would allow you to differentiate betweenxsi:niland omittance (nil when specified and null, omitted when not specified). However, this only works withXmlSerializer.