假设我们有以下复杂类型:
<complexType name="NiceType"> <sequence> <element name="niceElem" nillable="true" type="int" minOccurs="0" /> </sequence> </complexType>
元素显式设置为null(示例1):
<niceType> <niceElem xsi:nil="true"/> </niceType>
元素省略(例2):
<niceType> </niceType>
一般的解析器,例如JAX-B实现或.NET等,例如WCF的XML模块,是否能够分辨上面的示例1和示例2之间的区别?换句话说,您是否能够以可互操作的方式组合两个NULL表示 – 如示例中所示 – 以便传达不同的NULL阴影?
解决方法
XmlSerializer确实处理xsi:nil:在该上下文中它意味着与省略的节点相同;您可以使用XmlSerializer通过使用XmlSerializerFormatterattribute标记DataContracts来进行WCF序列化.
DataContractSerializer确实使用了属性:但是我不确定它使用它们的所有规则是什么(一种情况是circular references) – 它更可能省略元素.我不认为你应该将xsi:nil传递给DataContractSerializer,除非它在这种情况下使用它 – 因为DataContractSerializer是围绕假设设计的,以提高de /序列化性能.
从spec开始,它看起来像最初的设计工作方式类似于JavaScript null和undefined – 其中null(xsi:nil)是一个有效值,undefined(省略)是整个不存在的值;特别是对于复杂类型 – 您可以提供元素但省略它的内容(即使根据模式需要内容).
一般来说,我会避免它.这是非直观的 – 我认为我没有看到使用它的REST / SOAP API(除了专门使用它的InfoPath);大多数只使用null = undefined. xmlns声明和它的用法也会占用一些额外的宝贵字节.
奖励标记:如果您将元素设为可选且不可为空(例如xsd:int),则C#生成器提供< Name> Specified属性 – 您可以像这样添加自己的属性.这将允许您区分xsi:nil和omittance(指定时为nil,null,未指定时省略).但是,这仅适用于XmlSerializer.