代码之家  ›  专栏  ›  技术社区  ›  mfanto

派生类的XML序列化

  •  1
  • mfanto  · 技术社区  · 15 年前

    我有一个元素数组,需要使用XmlSerializer进行序列化。我遇到的问题是,我有两个派生类,并对它们进行序列化,使它们具有公共基的元素名,但似乎不起作用。

    因此,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 回复  |  直到 13 年前
        1
  •  5
  •   David McEwing    15 年前

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

        2
  •  1
  •   Iravanchi    15 年前

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

    如果能用两个不同的名字,那就行了。它们不必与派生类同名,只需给xmlserialization一个线索来确定哪个是哪个。

    使用xmlreader/writer进行自定义序列化始终是可能的,但它比简单的xml serialization要花费更多的时间(特别是如果您不是一个经验丰富的xml爱好者!)

    在这种情况下,我要做的是创建类的中间层次结构,并在代码中编写简单的转换。因此,最初的对象首先被转换成一个中间结构,可以由XML序列化处理。

    例如,在您的例子中,您可以创建一个类似于base的类(我称之为baseserializable),并将derived1和derived2的数据填充到这个类中。baseserializable可以由xmlserialization处理。在反序列化时,您将从xmlserialization中获得一个baseserializable,然后确定(使用字段/属性的内容)应实例化哪个派生的1/derived2类。因此,在实践中,您使用自定义代码对序列化的一小部分进行编码,剩下的部分留给XML序列化库。

        3
  •  0
  •   Community CDub    7 年前

    经过长时间的搜索,我在StackOverflow上找到了以下文章: 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 属性。