【问题标题】:XML Serialization and empty collectionsXML 序列化和空集合
【发布时间】:2008-09-16 03:59:47
【问题描述】:

我有一个属性定义为:

[XmlArray("delete", IsNullable = true)]
[XmlArrayItem("contact", typeof(ContactEvent)),
 XmlArrayItem("sms", typeof(SmsEvent))]
public List<Event> Delete { get; set; }

如果列表删除没有项目

<delete />

被发射。如果 List 删除设置为 null

<delete xsi:nil="true" />

被发射。如果集合没有项目,有没有办法使用属性来获取不发出删除元素?

Greg - 非常感谢,我什至没有阅读 IsNullable 文档,只是假设它表示不需要。

Rob Cooper - 我试图避免 ISerializable,但 Gregs 的建议有效。我确实遇到了您在 (1) 中概述的问题,如果集合长度为零,我只返回 null 就破坏了一堆代码。为了解决这个问题,我创建了一个 EventsBuilder 类(我正在序列化的类称为 Events),它管理 Events 类的底层对象的所有生命周期/创建,这些对象吐出我们的 Events 类进行序列化。

【问题讨论】:

标签: c# xml-serialization


【解决方案1】:

我遇到了同样的问题,如果字段为空或 0,我不希望输出元素。 输出的 XML 不能使用 xsi:null="true"(按设计)。

我在某处读到,如果您包含一个 bool 类型的属性,该属性与您要控制的字段名称相同但附加了“指定”,则 XMLSerializer 将检查此属性的返回值以确定相应的字段应包括在内。

在不实现 IXMLSerializer 的情况下实现这一点:

public List<Event> Delete { get; set; }
[XMLIgnore]
public bool DeleteSpecified
{
 get
 {
   bool isRendered = false;
   if (Delete != null)
   {
     isRendered = (Delete.Count > 0);
   } 

   return isRendered;
 }
 set
 {
 }
}

【讨论】:

  • geekswithblogs.net/shahed/archive/2007/07/11/113881.aspx 是一篇解释这种机制的文章。
  • 进一步阅读此方法仅适用于值类型。
  • 这似乎适用于非值类型,如上面的列表所示。为简洁起见,您可以将代码缩短为: get { return Delete != null && Delete.Count > 0; }
【解决方案2】:

如果您设置 IsNullable=false 或只是将其删除(默认为 false),则不会发出“删除”元素。这仅在集合等于 null 时才有效。

我的猜测是,.NET 中的“可空性”与 XML 中的可空元素(由 xml:nil 属性标记的元素)之间存在混淆。 XmlArrayAttribute.IsNullable 属性控制后者。

【讨论】:

  • 这不能回答问题? “如果集合没有项目,是否使用属性来获取不发出删除元素?”这基本上就是提问者现在所拥有的?
【解决方案3】:

首先,我会问自己“什么是序列化?”。

XmlSerializer 正在做它应该做的事情,将对象的当前状态保存到 XML。现在,我不确定为什么当前行为不适合您,因为如果您已初始化 List,那么它初始化。

我认为你在这里有三个选择:

  1. 如果集合有 0 个项目,则向 Getter 添加代码以返回 null。不过,这可能会弄乱您拥有的其他代码。
  2. 实现 IXmlSerializable 接口并自己完成所有工作。
  3. 如果这是一个常见的过程,那么您可能想看看我的问题“XML Serialization and Inherited Types” - 是的,我知道它处理另一个问题,但它向您展示了如何创建一个通用的中间序列化类,然后可以被“固定”以允许封装序列化过程。您可以创建一个类似的类来处理覆盖 null/零项集合的默认过程。

我希望这会有所帮助。

【讨论】:

    【解决方案4】:

    您始终可以实现 IXmlSerializer 并手动执行序列化。

    有关示例,请参阅 http://www.codeproject.com/KB/cs/IXmlSerializable.aspx

    【讨论】:

      猜你喜欢
      • 2011-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-31
      • 2012-04-09
      • 1970-01-01
      相关资源
      最近更新 更多