XML-парсеры (например, XmlReader
, XmlDocument
, XDocument
) не обрабатывают xsi:nil
специально - вы все еще видите элемент в потоке / документе.
XmlSerializer
обрабатывает xsi:nil
: в этом контексте это означает то же самое, что и пропущенный узел; Вы можете сделать сериализацию WCF, используя XmlSerializer
, отметив DataContract
s, используя XmlSerializerFormatterAttribute
.
DataContractSerializer
действительно использует атрибут: однако я не уверен, каковы все правила его использования (один случай - циклические ссылки ) - гораздо более вероятно, что элементы будут опущены. Я не думаю, что вам следует передавать xsi:nil
на DataContractSerializer
, если он не использует его в этом случае - поскольку DataContractSerializer
разработан с учетом допущений для улучшения производительности де-сериализации.
Из spec похоже, что он изначально был разработан для работы как JavaScript null
и undefined
- где null
(xsi:nil
) является допустимым значением и undefined
( опущено) - полное отсутствие значения; особенно со сложными типами - вы можете предоставить элемент, но пропустить его содержимое (даже если содержимое требуется согласно схеме).
В общем, я бы этого избегал. Это не интуитивно понятно - я не думаю, что видел REST / SOAP API там, где он используется (кроме InfoPath, который использует его исключительно); большинство просто используют null = undefined
. Объявление xmlns и его использование также потребляют несколько дополнительных ценных байтов.
Бонусные метки: Если вы сделаете элемент необязательным и не обнуляемым (например, xsd:int
), генератор C # предоставляет свойство <Name>Specified
- вы можете добавить свои собственные свойства, подобные этому. Это позволит вам различать xsi:nil
и пропуск (ноль, если указано, и ноль, опускается, если не указано). Однако это работает только с XmlSerializer
.