C# XML 序列化和空集合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/69296/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
XML Serialization and empty collections
提问by Nic Strong
I have a a property defined as:
我将 aa 属性定义为:
[XmlArray("delete", IsNullable = true)]
[XmlArrayItem("contact", typeof(ContactEvent)),
XmlArrayItem("sms", typeof(SmsEvent))]
public List<Event> Delete { get; set; }
If the List<> Delete has no items
如果 List<> Delete 没有项目
<delete />
is emitted. If the List<> Delete is set to null
被发射。如果 List<> Delete 设置为 null
<delete xsi:nil="true" />
is emitted. Is there a way using attributes to get the delete element not to be emitted if the collection has no items?
被发射。如果集合没有项目,是否可以使用属性来获取不发出删除元素的方法?
Greg- Perfect thanks, I didn't even read the IsNullable documentation just assumed it was signalling it as not required.
Greg- 非常感谢,我什至没有阅读 IsNullable 文档,只是假设它表示不需要它。
Rob Cooper- I was trying to avoid ISerializable, but Gregs suggestion works. I did run into the problem you outlined in (1), I broke a bunch of code by just returning null if the collection was zero length. To get around this I created a EventsBuilder class (the class I am serializing is called Events) that managed all the lifetime/creation of the underlying objects of the Events class that spits our Events classes for serialization.
Rob Cooper- 我试图避免 ISerializable,但 Gregs 的建议有效。我确实遇到了您在 (1) 中概述的问题,如果集合长度为零,我只返回 null 就破坏了一堆代码。为了解决这个问题,我创建了一个 EventsBuilder 类(我正在序列化的类称为 Events),它管理 Events 类的底层对象的所有生命周期/创建,这些对象将我们的 Events 类用于序列化。
采纳答案by GregK
If you set IsNullable=false or just remove it (it is false by default), then the "delete" element will not be emitted. This will work only if the collection equals to null.
如果您设置 IsNullable=false 或只是将其删除(默认情况下为 false),则不会发出“删除”元素。这仅在集合等于 null 时才有效。
My guess is that there is a confusion between "nullability" in terms of .NET, and the one related to nullable elements in XML -- those that are marked by xml:nil attribute. XmlArrayAttribute.IsNullable property controls the latter.
我的猜测是 .NET 中的“可空性”与 XML 中与可空元素相关的可空性之间存在混淆——那些由 xml:nil 属性标记的元素。XmlArrayAttribute.IsNullable 属性控制后者。
回答by Craig Eddy
You could always implement IXmlSerializer and perform the serialization manually.
您始终可以实现 IXmlSerializer 并手动执行序列化。
See http://www.codeproject.com/KB/cs/IXmlSerializable.aspxfor an example.
有关示例,请参见http://www.codeproject.com/KB/cs/IXmlSerializable.aspx。
回答by Rob Cooper
First off, I would say ask yourself "What is Serialization?".
首先,我会问自己“什么是序列化?”。
The XmlSerializeris doing exactly what it is supposed to be doing, persisting the current state of the object to XML. Now, I am not sure why the current behaviour is not "right" for you, since if you have initialized the List, then it isinitialized.
该XmlSerializer的是做什么是应该做的,持久对象的当前状态为XML。现在,我不确定为什么当前的行为不适合你,因为如果你已经初始化了 List,那么它就会被初始化。
I think you have three options here:
我认为你在这里有三个选择:
- Add code to the Getter to return null if the collection has 0 items. This may mess up other code you have though.
- Implement the IXmlSerializableinterface and do all the work yourself.
- If this is a common process, then you may want to look at my question "XML Serialization and Inherited Types" - Yes, I know it deals with another issue, but it shows you how to create a generic intermediary serialization class that can then be "bolted on" to allow a serilization process to be encapsulated. You could create a similar class to deal with overriding the default process for null/zero-item collections.
- 如果集合有 0 个项目,则向 Getter 添加代码以返回 null。不过,这可能会弄乱您拥有的其他代码。
- 实现IXmlSerializable接口并自己完成所有工作。
- 如果这是一个常见的过程,那么您可能想看看我的问题“ XML 序列化和继承类型” - 是的,我知道它处理另一个问题,但它向您展示了如何创建一个通用的中间序列化类,然后可以“固定”以允许封装灭菌过程。您可以创建一个类似的类来处理覆盖空/零项集合的默认过程。
I hope this helps.
我希望这有帮助。
回答by theahuramazda
I've had the same issue where I did not want an element outputted if the field is empty or 0. The XML outputted could not use xsi:null="true" (by design).
我遇到了同样的问题,如果字段为空或为 0,我不希望输出元素。输出的 XML 不能使用 xsi:null="true"(按设计)。
I've read somewhere that if you include a property of type bool with the same name as the field you want to control but appended with 'Specified', the XMLSerializer will check the return value of this property to determine if the corresponding field should be included.
我在某处读到,如果您包含一个与您要控制的字段同名但附加有“指定”的 bool 类型的属性,则 XMLSerializer 将检查此属性的返回值以确定相应的字段是否应为包括。
To achieve this without implementing IXMLSerializer:
要在不实施 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
{
}
}