XML序列化子类

本文关键字:子类 序列化 XML | 更新日期: 2023-09-27 18:02:18

我有一个类:

public abstract class BaseClass
{
}
public class FirstChild:BaseClass
{
}
public class SecondChild:BaseClass
{
}
public class Request
{
public BaseClass Child {get;set;}
}

我已经在所有类上添加了serializable属性,并在Baseclass、firstchild和secondchild类上包含了XmlInclude。

I want to achieve this:
<Request>
   <FirstChild/>
</Request>

<Request>
   <SecondChild/>
</Request>

我使用:

创建请求
Request request = new Request();
request.Child = new FirstChild();

然后序列化。

但是我一直收到这个

<Request  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Type  xsi:type="FirstChild">
</Type>
</Request>

你能指出我哪里做得不对吗?

XML序列化子类

为了做到这一点,您需要使用XmlArrayItem或XmlElement属性。另外,如果你想让子类实例成为你的Child元素的子元素,如果你把Child属性当作一个长度为1的BaseClass[],那就容易多了。

因此你的类看起来像这样:

public abstract class BaseClass
{
}
public class FirstChild:BaseClass
{
}
public class SecondChild:BaseClass
{
}
public class Request
{
        [XmlArrayItem(Type = typeof(FirstChild), ElementName = "FirstChild")]
        [XmlArrayItem(Type = typeof(SecondChild), ElementName = "SecondChild")] 
        public BaseClass[] Child {get;set;}
}

这将生成您要查找的XML

你能试一下这段代码吗?另外,我假设你的实际类中有属性。

using (MemoryStream ms = new MemoryStream())
{
    XmlWriterSettings xrs = new XmlWriterSettings();
    xrs.Encoding = Encoding.UTF8;
    using (XmlWriter writer = XmlWriter.Create(ms, xrs))
    {
        XmlSerializer serializer = new XmlSerializer(obj.GetType());
        serializer.Serialize(writer, obj);
        writer.Flush();
    }
    using (StreamReader sr = new StreamReader(ms))
    {
        ms.Position = 0;
        xml = sr.ReadToEnd();
    }
}

我看不出有什么简单的方法可以做到这一点。为此,我将创建一个帮助类RequestMemento:

using System;
using System.IO;
using System.Xml.Serialization;
using System.ComponentModel;
public abstract class BaseClass
{}
public class FirstChild:BaseClass
{}
public class SecondChild:BaseClass
{}
[XmlRoot("Request")]
[XmlType("Request")]
public class RequestMemento
{
    [DefaultValue(null)]
    public FirstChild First { get; set; }
    [DefaultValue(null)]
    public SecondChild Second { get; set; }
    [XmlIgnore]
    public BaseClass Child
    {
        get
        {
            return (BaseClass)First ?? (BaseClass)Second;
        }
        set
        {
            First = value as FirstChild;
            Second = value as SecondChild;
        }
    }
}
class App
{
    static void Main()
    {
        var memento = new RequestMemento();
        memento.Child = new FirstChild();
        XmlSerializer serializer = new XmlSerializer(typeof(RequestMemento));
        using (var writer = new StreamWriter("1.xml"))
        {
            serializer.Serialize(writer, memento);
        }
    }
}