【问题标题】:XML Serialization of Derived Classes派生类的 XML 序列化
【发布时间】:2011-11-14 16:11:39
【问题描述】:

我有一个需要使用 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()
    {

    }
}

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

【问题讨论】:

    标签: c# xml-serialization


    【解决方案1】:

    XML 序列化包括序列化和反序列化例程。因此,如果您确实设法做到了这一点,那么在反序列化生成的 XML 结构时,序列化程序将无法计算出要使用的类型。根据我的经验,最好使用两个不同的名称或使用 XmlWriter 和 XmlReader 类的自定义序列化器/反序列化器。

    【讨论】:

      【解决方案2】:

      大卫的回答是正确的。这对于纯 XmlSerialization 是不可能的,因为它无法从 XML 元素的内容确定在反序列化时应该实例化哪个派生类。

      如果可以使用两个不同的名称,它会起作用。它们不必与派生类同名,您只需要给 XmlSerialization 一个线索来确定哪个是哪个。

      使用 XmlReader/Writer 自定义序列化始终是可能的,但它比简单的 XmlSerialization 更耗时(特别是如果您不是经验丰富的 XML 瘾君子!)

      在这种情况下,我所做的是创建类的中间层次结构,并在代码中编写简单的转换。因此,原始对象首先被转换为可以由 XmlSerialization 处理的中间结构。

      例如,在您的情况下,您可以创建一个类似于 Base 的类(我称之为 BaseSerializable),并将 Derived1 和 Derived2 的数据填充到其中。 BaseSerializable 可以由 XmlSerialization 处理。反序列化时,您从 XmlSerialization 获得 BaseSerializable,然后确定(使用字段/属性的内容)应实例化哪些 Derived1/Derived2 类。因此,在实践中,您使用自定义代码对序列化的一小部分进行编码,并将其余部分留给 XmlSerialization 库。

      【讨论】:

      • 谢谢。既然我从需要反序列化的角度来看,你和大卫的答案是有道理的。我想我已经假设有某种方法可以指定,因为 XML 中有一些属性 =“Derived1”,所以我可以手动告诉它要创建哪个对象。
      【解决方案3】:

      经过长时间寻找替代方案后,我在 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 属性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多