XML序列化子类

时间:2011-07-14 13:34:07

标签: c# xml-serialization

我有一个班级:

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>

你能指出我做得不对吗?

3 个答案:

答案 0 :(得分:5)

为此,您需要使用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。

答案 1 :(得分:0)

你能试试这段代码..我也假设你的实际课程中有属性。

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();
    }
}

答案 2 :(得分:0)

我没有看到任何简单的方法来做到这一点。我会为此创建一个帮助类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);
        }
    }
}