5

XML 解析器/反序列化器通常能够区分显式设置为 null 的 nillable 元素和遗漏的可选元素之间的区别吗?

假设我们有以下复杂类型:

<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 的不同阴影?

4

1 回答 1

2

XML 解析器(例如XmlReader, XmlDocumentXDocument不会进行xsi:nil特殊处理 - 您仍然可以在流/文档中看到该元素。

XmlSerializer确实处理xsi:nil:在该上下文中,它与省略节点的含义相同;XmlSerializer您可以通过使用 .标记您DataContract的 s 来使 WCF 序列化XmlSerializerFormatterAttribute

DataContractSerializer确实使用了该属性:但是我不确定使用它们的所有规则是什么(一种情况是循环引用)-它更有可能省略元素。我认为你不应该传递xsi:nil给它,DataContractSerializer除非它在这种情况下使用它——因为DataContractSerializer它是围绕提高反/序列化性能的假设而设计的。

规范看来,它最初被设计为像 JavaScript 一样工作,null并且undefined- 其中null( xsi:nil) 是一个有效值,而undefined(省略) 是一个完全不存在的值;特别是对于复杂类型 - 您可以提供元素但省略其内容(即使根据架构需要内容)。

一般来说,我会避免它。这是不直观的——我认为我没有见过使用它的 REST/SOAP API(InfoPath 除外,它专门使用它);大多数只是使用null = undefined. xmlns 声明和它的使用也消耗了一些额外的有价值的字节。

加分项:如果您将元素设为可选并且它不可为空(例如xsd:int),C# 生成器会提供一个<Name>Specified属性 - 您可以像这样添加自己的属性。这将允许您区分xsi:nil和省略(指定时为 nil 和 null,未指定时省略)。但是,这仅适用于XmlSerializer.

于 2012-01-03T08:52:16.730 回答