XML序列化和空集合
我有一个属性定义为:
[XmlArray("delete", IsNullable = true)] [XmlArrayItem("contact", typeof(ContactEvent)), XmlArrayItem("sms", typeof(SmsEvent))] public List<Event> Delete { get; set; }
如果List <> Delete没有项目
<delete />
被发射。如果List <> Delete设置为null
<delete xsi:nil="true" />
被发射。如果集合中没有项目,有没有一种方法可以使用属性来使delete元素不被发出?
Greg Perfect,谢谢,我什至没有读过IsNullable文档,只是假设它表明不需要使用它。
罗伯·库珀(Rob Cooper)我试图避免ISerializable,但格雷格斯(Gregs)的建议行之有效。我确实遇到了我们在(1)中概述的问题,如果集合的长度为零,我只是通过返回null来破坏了一堆代码。为了解决这个问题,我创建了一个EventsBuilder类(我正在序列化的类称为事件),该类管理Events类的基础对象的所有生存期/创建时间,这些事件/事件将我们的Events类吐出进行序列化。
解决方案
回答
我们始终可以实现IXmlSerializer并手动执行序列化。
有关示例,请参见http://www.codeproject.com/KB/cs/IXmlSerializable.aspx。
回答
如果设置IsNullable = false或者将其删除(默认情况下为false),则不会发出"删除"元素。仅当collection等于null时,此方法才有效。
我的猜测是,在.NET方面的"可空性"和与XML中可空元素相关的那些之间存在混淆,这些元素由xml:nil属性标记。 XmlArrayAttribute.IsNullable属性控制后者。
回答
首先,我要问自己"什么是序列化?"。
XmlSerializer完全按照预期的方式运行,将对象的当前状态持久保存为XML。现在,我不确定为什么当前行为对我们而言不是"正确"的,因为如果我们已经初始化了列表,那么它将被初始化。
我认为我们在这里有三个选择:
- 如果该集合包含0个项目,则将代码添加到Getter以返回null。这可能会弄乱我们拥有的其他代码。
- 实现IXmlSerializable接口并自己完成所有工作。
- 如果这是一个常见的过程,那么我们可能想看一下我的问题" XML序列化和继承的类型"-是的,我知道它涉及另一个问题,但是它向我们展示了如何创建一个通用的中介序列化类,该类可以"固定"以允许系列化过程被封装。我们可以创建一个类似的类来处理覆盖空/零项目集合的默认过程。
我希望这有帮助。
回答
我遇到了同样的问题,如果字段为空或者为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 { } }