我有一个继承自Collection的简单类,并添加了几个属性。我需要将此类序列化为XML,但XMLSerializer会忽略我的其他属性。
我认为这是因为XMLSerializer提供ICollection和IEnumerable对象的特殊处理。最好的方法是什么?
以下是一些示例代码:
using System.Collections.ObjectModel;
using System.IO;
using System.Xml.Serialization;
namespace SerialiseCollection
{
class Program
{
static void Main(string[] args)
{
var c = new MyCollection();
c.Add("Hello");
c.Add("Goodbye");
var serializer = new XmlSerializer(typeof(MyCollection));
using (var writer = new StreamWriter("test.xml"))
serializer.Serialize(writer, c);
}
}
[XmlRoot("MyCollection")]
public class MyCollection : Collection<string>
{
[XmlAttribute()]
public string MyAttribute { get; set; }
public MyCollection()
{
this.MyAttribute = "SerializeThis";
}
}
}
这将输出以下XML(注意MyCollection元素中缺少MyAttribute):
<?xml version="1.0" encoding="utf-8"?>
<MyCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>Hello</string>
<string>Goodbye</string>
</MyCollection>
我想要的是
<MyCollection MyAttribute="SerializeThis"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>Hello</string>
<string>Goodbye</string>
</MyCollection>
有什么想法吗?越简单越好。感谢。
答案 0 :(得分:13)
收藏品通常不会为额外的物业提供好地方。在序列化和数据绑定期间,如果项目看起来像集合(IList
,IEnumerable
等,它们将被忽略 - 取决于场景)。
如果是我,我会封装收藏品 - 即。
[Serializable]
public class MyCollectionWrapper {
[XmlAttribute]
public string SomeProp {get;set;} // custom props etc
[XmlAttribute]
public int SomeOtherProp {get;set;} // custom props etc
public Collection<string> Items {get;set;} // the items
}
另一种选择是实现IXmlSerializable
(相当多的工作),但这仍然不适用于数据绑定等。基本上,这不是预期的用法。
答案 1 :(得分:13)
如果你进行封装,正如Marc Gravell建议的那样,这篇文章的开头解释了如何让你的XML看起来与你描述的完全一样。
即代替:
<MyCollection MyAttribute="SerializeThis"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Items>
<string>Hello</string>
<string>Goodbye</string>
<Items>
</MyCollection>
你可以拥有:
<MyCollection MyAttribute="SerializeThis"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>Hello</string>
<string>Goodbye</string>
</MyCollection>
答案 2 :(得分:1)
正如尼尔·惠特克(Neil Whitaker)建议的那样,如果他的链接死了......
创建内部集合以存储字符串并应用XmlElement属性来屏蔽集合名称。生成相同的xml输出,就像MyCollection继承自Collection一样,但也序列化父元素上的属性。
[XmlRoot("MyCollection")]
public class MyCollection
{
[XmlAttribute()]
public string MyAttribute { get; set; }
[XmlElement("string")]
public Collection<string> unserializedCollectionName { get; set; }
public MyCollection()
{
this.MyAttribute = "SerializeThis";
this.unserializedCollectionName = new Collection<string>();
this.unserializedCollectionName.Add("Hello");
this.unserializedCollectionName.Add("Goodbye");
}
}
答案 3 :(得分:0)
我一直在与Romaroo同样的问题进行斗争(想要在实现ICollection的类的xml序列化中添加属性)。我没有找到任何方法来公开集合类中的属性。我甚至尝试使用XmlAttribute标记并使我的属性显示为根节点的属性,但也没有运气。然而,我能够在我的类上使用XmlRoot标记从“ArrayOf ...”重命名它。以下是您感兴趣的一些参考资料:
答案 4 :(得分:0)