我有一系列元素需要使用XmlSerializer进行序列化。我遇到的问题是我有2个派生类,并序列化它们,因此它们有一个共同基础的元素名称,似乎不起作用。
所以,这就是XML的外观:
<Root>
<Base> foo </Base>
</Root>
相反,我正在
<Root>
<Derived1> foo </Derived1>
</Root>
我序列化的元素数组的代码是
private object[] m_nodes;
[System.Xml.Serialization.XmlElementAttribute("Base", typeof(Derived1)]
[System.Xml.Serialization.XmlElementAttribute("Base", typeof(Derived2)]
public object[] Nodes
{
get
{
return this.m_nodes;
}
set
{
this.m_nodes = value;
}
}
使用上面的代码,我得知节点有一个反射错误。如果我将XmlEelementAttributes中的“Base”更改为“Derived1”和Derived2“,它可以工作,但元素名称不正确。
[System.Xml.Serialization.XmlInclude(typeof(Derived1))]
public abstract class Base
{
public Base()
{
}
}
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public class Derived1: Base
{
public Derived1()
{
}
}
非常感谢任何帮助。非常感谢。
答案 0 :(得分:5)
XML序列化包括序列化和反序列化例程。因此,如果您确实设法执行此操作,那么序列化程序将无法确定在反序列化生成的XML结构时要使用的类型。根据我的经验,最好使用两个不同的名称或使用XmlWriter和XmlReader类使用自定义序列化器/反序列化器。
答案 1 :(得分:1)
大卫的回答是正确的。裸XmlSerialization是不可能的,因为它无法确定在反序列化时应该从XML元素的内容中实例化哪个派生类。
如果可以使用两个不同的名称,它将起作用。它们不必与派生类同名,您只需要给XmlSerialization一个线索来确定哪个是哪个。
使用XmlReader / Writer的自定义序列化总是可行的,但它比简单的XmlSerialization更耗时(特别是如果你不是一个有经验的XML上瘾者!)
在这种情况下我做的是创建一个类的中间层次结构,并在代码中编写简单的转换。因此,原始对象首先转换为可由XmlSerialization处理的中间结构。
例如,在您的情况下,您可以创建一个类似于Base的类(我称之为BaseSerializable),并将Derived1和Derived2的数据填入其中。 BaseSerializable可以由XmlSerialization处理。反序列化时,从XmlSerialization中获取BaseSerializable,然后确定(使用字段/属性的内容)应该实例化哪个Derived1 / Derived2类。因此,在实践中,您使用自定义代码编写序列化的一小部分,并将其余部分留给XmlSerialization库。
答案 2 :(得分:0)
经过长时间搜索备选方案后,我在Stack Overflow上发现了以下帖子:How do I use an XmlSerializer to deserialize an object that might be of a base or derived class without knowing the type beforehand?
我尝试了它,它也适用于序列化。所以在序列化时,它也会给你一个很好的输出。对于数组,您需要使用XmlArrayItem
属性。