Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do XML parsers tell the difference between xsi:nil="true" and omitted elements?

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?

like image 862
nize Avatar asked Nov 05 '22 08:11

nize


1 Answers

XML parsers (e.g. XmlReader, XmlDocument, XDocument) don't treat xsi:nil specially - you still see the element in the stream/document.

XmlSerializer does handle xsi:nil: within that context it means the same thing as an omitted node; you can make WCF serialize using XmlSerializer by marking your DataContracts using XmlSerializerFormatterAttribute.

DataContractSerializer does 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 pass xsi:nil to DataContractSerializer unless it uses it in that case - as DataContractSerializer is designed around assumptions to improve de/serialization performance.

From the spec it looks like it was originally designed to work like the JavaScript null and undefined - where null (xsi:nil) is a valid value and undefined (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>Specified property - you can add your own properties like this. This would allow you to differentiate between xsi:nil and omittance (nil when specified and null, omitted when not specified). However, this only works with XmlSerializer.

like image 167
Jonathan Dickinson Avatar answered Nov 13 '22 16:11

Jonathan Dickinson