【问题标题】:Do XML parsers tell the difference between xsi:nil="true" and omitted elements?XML 解析器能区分 xsi:nil="true" 和省略的元素吗?
【发布时间】:2012-01-03 16:52:16
【问题描述】:

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?

【问题讨论】:

  • 出色的措辞 - “NULL 的不同深浅” - 将成为一个体面的乐队名称!
  • 一个好主意,有点书呆子乐队,但无论如何:)

标签: xml wcf jaxb nullable minoccurs


【解决方案1】:

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

XmlSerializer 确实处理xsi:nil:在这种情况下,它与省略节点的含义相同;您可以通过使用XmlSerializerFormatterAttribute 标记您的DataContracts 来使用XmlSerializer 进行WCF 序列化。

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

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

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

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

【讨论】:

  • 我想结合 nillable="true" 和 minOccurs="0" 的原因是能够发送更新消息(在 Web 服务调用中),您可以在其中区分哪些元素不更新,更新哪些,删除哪些。在该设计中,将省略不更新的元素。请参阅this post。您的意见让我怀疑这种方法。
  • 怎么样:&lt;update xmlns:sync="http://foo"&gt;&lt;item id="100"&gt;&lt;node1 sync:action="delete" /&gt;&lt;node2 sync:action="update" /&gt;&lt;/item&gt;&lt;/update&gt;。我个人觉得xsi:nil很臭;出于完全相同的原因,你不得不问一个问题:不清楚它到底是什么意思;并且 API 支持充其量是参差不齐的。不过,奖励分数位会帮助您解决问题(除了XmlSerializerFormatter)。
  • Spotty API 支持在 SOA 服务方面并不是一件好事。感谢您指出了这一点。异构 WS 框架必须能够正确解析它。您提出的建议类似于this post 中的备选Alt 2.1。反对在元素中包含操作属性的一个论点可能是,您将“业务文档”类型与应该应用于它们的操作相关的动词弄乱了。
  • @nize 处理它的另一种方法是提供补充文档,说明如何应用更改。例如。 &lt;package&gt;&lt;originalRootItem&gt;&lt;item id="1" /&gt;&lt;/originalRootItem&gt;&lt;delta&gt;&lt;update ref="1" /&gt;&lt;/delta&gt;&lt;/package&gt;.
猜你喜欢
  • 1970-01-01
  • 2021-02-07
  • 1970-01-01
  • 2010-12-30
  • 2019-07-20
  • 2019-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多