XML 序列化和空集合

问题描述 投票:0回答:5

我有一个属性定义为:

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

如果List<>删除没有项目

<delete />
发出

。如果List<>Delete设置为null

<delete xsi:nil="true" />
发出

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

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

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

c# xml-serialization
5个回答
20
投票

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

我在某处读到,如果您包含一个 bool 类型的属性,其名称与您想要控制的字段相同,但附加了“Specified”,则 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
 {
 }
}

5
投票

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

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


1
投票

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

XmlSerializer 正在做它应该做的事情,将对象的当前状态保存到 XML。现在,我不确定为什么当前的行为对您来说不“正确”,因为如果您已经初始化了列表,那么它is已初始化。

我认为你有三个选择:

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

我希望这有帮助。


0
投票

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

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


0
投票

感谢 Christophe Bertrand,我发现这在使用 XmlSerializer.Serialize 时适用于对象和值类型:

public List<Event> Delete { get; set; }
public bool ShouldSerializeDelete () {
{ 
  return Delete != null && Delete.Count > 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.