Как десериализовать XML, не зная заранее типа? - PullRequest
13 голосов
/ 22 апреля 2009

Скажем, у меня есть пара основных объектов, таких как:

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

За исключением того, что я мог бы передать ему файл XML для любого класса, который происходит от Base, и будет создан правильный класс.

Мне кажется, я мог бы прочитать имя корневого узла XML и использовать инструкцию switch для создания правильного XmlSerializer, но мне было интересно, есть ли более простой способ.

Ответы [ 3 ]

9 голосов
/ 22 апреля 2009

Вы можете прочитать корневой узел файла XML и вместо использования оператора switch вы можете написать свой код следующим образом -

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

Я не думаю, что есть другой способ, кроме чтения XML, потому что, если вы не знаете тип, вы ничего не можете сделать.

8 голосов
/ 05 мая 2009

Используйте атрибут [XmlInclude] в базовом классе, чтобы сообщить сериализатору XML о производных классах, чтобы он мог выяснить, что создавать. Ваш последний фрагмент кода должен работать правильно.

0 голосов
/ 05 мая 2009

Насколько я знаю, не существует более простого способа сделать это.

Лично я предпочитаю более универсальное решение (поскольку я должен сериализовать множество различных классов в моем коде): чтобы имя типа сериализовалось вместе со значением.

Вы можете взглянуть на этот вопрос для некоторых деталей: Сериализация в XML и включение типа сериализованного объекта

...