如何在不事先知道类型的情况下反序列化XML?

16

假设我有一些基本对象,如下:

[Serializable]
public class Base
{

    public string Property1 { get; set; }
    public int Property2 { get; set; }
}

[Serializable]
public class Sub: Base
{
    public List<string> Property3 { get; set; }

    public Sub():base()
    {
        Property3 = new List<string>();
    }        
}

然后我像这样对它们进行序列化:

Sub s = new Sub {Property1 = "subtest", Property2 = 1000};
s.Property3.Add("item 1");
s.Property3.Add("item 2");

XmlSerializer sFormater = new XmlSerializer(typeof(Sub));
using (FileStream fStream = new FileStream("SubData.xml", 
    FileMode.Create, FileAccess.Write, FileShare.None))
{
    sFormater.Serialize(fStream, s);
}

我该如何进行反序列化,以便正确地获取类对象?

也就是说,我希望得到类似以下的东西:

XmlSerializer bFormater = new XmlSerializer(typeof (Base));
Base newBase;
using (FileStream fStream = new FileStream("BaseData.xml", 
    FileMode.Open, FileAccess.Read, FileShare.Read))
{
    newBase = (Base) bFormater.Deserialize(fStream);
}

我可以向它传递任何从Base继承的类的XML文件,并且正确的类将被创建。

我在考虑读取XML的根节点名称并使用switch语句创建正确的XmlSerializer,但我想知道是否有更简单的方法。


好的。刚刚检查了一下,它抛出了一个异常。我已经删除了最后一段。 - Kirtan
好的,我删除了我的评论,因为它已经不适用了。 - Ray
3个回答

10

您可以读取XML文件的根节点,而不是使用switch语句,您可以像这样编写代码 -

Type yourType = Type.GetType("Your Type");
XmlSerializer xs = new XmlSerializer(yourType);

我认为除了读取XML之外,没有其他的方式,因为如果你不知道类型,你什么也做不了。


8

在您的基类上使用[XmlInclude]属性,告诉XML序列化程序有关派生类的信息,以便它能够确定要创建什么。然后,您的最后一个代码片段应该可以正常工作。


2
还有一件事,当我序列化子类时,需要使用在基类上创建的XmlSerializer(而不是子类)。 - Ray
在基类上使用 [Serializable, XmlInclude(typeof(Sub))] - politus

1
据我所知,没有更简单的方法来做到这一点。
我个人更喜欢一个更通用的解决方案(因为我必须在我的代码中序列化许多不同的类):将类型名称与值一起序列化。
您可以查看此问题以获取一些详细信息: 将对象序列化为XML并包括其类型

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接