问题
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?
回答1:
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 DataContract
s 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
.
来源:https://stackoverflow.com/questions/8709424/do-xml-parsers-tell-the-difference-between-xsinil-true-and-omitted-elements