XML解析器是否告诉xsi:nil ="true"和省略元素之间的区别?

niz*_*ize 5 xml wcf nullable jaxb minoccurs

XML解析器/反序列化器通常能够区分显式设置为null的可枚举元素和省略的可选元素吗?

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

<complexType name="NiceType">
  <sequence>
    <element name="niceElem" nillable="true" type="int" minOccurs="0" />
  </sequence>
</complexType>
Run Code Online (Sandbox Code Playgroud)

元素显式设置为null(示例1):

<niceType>
  <niceElem xsi:nil="true"/> 
</niceType>
Run Code Online (Sandbox Code Playgroud)

元素省略(例2):

<niceType>
</niceType>
Run Code Online (Sandbox Code Playgroud)

一般的解析器,例如JAX-B实现或.NET等,例如WCF的XML模块,是否能够分辨上面的示例1和示例2之间的区别?换句话说,您是否能够以可互操作的方式组合两个NULL表示 - 如示例中所示 - 以便传达不同的NULL阴影?

Jon*_*son 2

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

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

DataContractSerializer确实使用该属性:但是我不确定使用它们的所有规则是什么(一种情况是循环引用) - 它更有可能省略元素。我认为你不应该传递xsi:nilDataContractSerializer除非它在这种情况下使用它 - 正如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.

  • 我想组合 nillable="true" 和 minOccurs="0" 的原因是能够发送更新消息(在 Web 服务调用中),您可以在其中区分哪些元素不更新,哪些元素要更新以及要删除的内容。在该设计中,不更新的元素将被省略。请参阅[这篇文章](http://stackoverflow.com/questions/8709715/how-to-use-optional-attributes-in-web-service-update-messages-dtos)。你的意见让我对这种方法产生怀疑。 (2认同)
  • 怎么样:`&lt;update xmlns:sync="http://foo"&gt;&lt;item id="100"&gt;&lt;node1sync:action="delete"/&gt;&lt;node2sync:action="update"/&gt;&lt;/项目&gt;&lt;/更新&gt;`。我个人认为`xsi:nil`很臭;出于完全相同的原因,您必须提出一个有关它的问题:不清楚它到底意味着什么;API 支持也很不稳定。不过,奖励标记位将为您解决问题(除了“XmlSerializerFormatter”)。 (2认同)