派生类的XML序列化

时间:2009-10-11 22:49:47

标签: c# xml-serialization

我有一系列元素需要使用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()
    {

    }
}

非常感谢任何帮助。非常感谢。

3 个答案:

答案 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属性。