XML解析器/反序列化器通常能够区分nillable elements explicitly set to null and optional elements that are left out吗?
假设我们有以下复杂类型:
<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色调?
答案 0 :(得分:2)
XML解析器(例如XmlReader
,XmlDocument
,XDocument
)不会特别处理xsi:nil
- 您仍会在流/文档中看到该元素。
XmlSerializer
确实处理xsi:nil
:在该上下文中,它意味着与省略的节点相同;您可以使用XmlSerializer
使用DataContract
对XmlSerializerFormatterAttribute
进行序列化。
DataContractSerializer
确实使用了该属性:但是我不确定它使用它们的所有规则是什么(一种情况是circular references) - 它更可能省略元素。我不认为您应该将xsi:nil
传递给DataContractSerializer
,除非它在这种情况下使用它 - 因为DataContractSerializer
是围绕假设设计的,以提高de /序列化性能。
从spec看起来它原本设计为像JavaScript null
和undefined
一样工作 - 其中null
(xsi:nil
)是有效的value和undefined
(省略)是整个不存在的值;特别是对于复杂类型 - 您可以提供元素但省略它的内容(即使根据模式需要内容)。
总的来说,我会避免它。这是非直观的 - 我认为我没有看到使用它的REST / SOAP API(除了专门使用它的InfoPath);大多数只使用null = undefined
。 xmlns声明和它的用法也会占用一些额外的宝贵字节。
Bonus Marks:如果你使一个元素可选并且它不可为空(例如xsd:int
)C#生成器提供<Name>Specified
属性 - 你可以添加自己的属性像这样的属性。这将允许您区分xsi:nil
和省略(指定时为nil,null,未指定时省略)。但是,这仅适用于XmlSerializer
。