XML-десериализация списка‹›

Мне удалось сериализовать список объектов типа Word с помощью сериализации XML:

public static void WriteXML(string fileName)
{     
    System.Xml.Serialization.XmlSerializer writer =
        new System.Xml.Serialization.XmlSerializer(typeof(Word));
    System.IO.StreamWriter file = new System.IO.StreamWriter(
        fileName);
    foreach (var word in Words)
    {
        writer.Serialize(file, word);
    }
    file.Close();
}

У меня проблема с десериализацией этого списка. Я использую этот фрагмент кода: http://msdn.microsoft.com/en-us/library/vstudio/ms172872.aspx

Я изменил свой код на что-то вроде этого:

public static void ReadXML(string fileName)
{
    System.Xml.Serialization.XmlSerializer reader =
        new System.Xml.Serialization.XmlSerializer(typeof(Word));
    System.IO.StreamReader file = new System.IO.StreamReader(
        fileName);
    foreach (????)
    {
        Word word=new Word();
        word = (Word) reader.Deserialize(file);
        Words.Add(word); //Words is a List<Word>
    }
}

Конечно, цикл foreach() здесь не используется должным образом. Я просто понятия не имею, как это сделать.


person BuahahaXD    schedule 25.12.2012    source источник
comment
Мне любопытно: как выглядит сгенерированный XML после запуска кода сериализации?   -  person Kenneth K.    schedule 25.12.2012
comment
‹?xml version=1.0 encoding=utf-8?› ‹Word xmlns:xsi=w3.org /2001/XMLSchema-instance xmlns:xsd=w3.org/2001/XMLSchema› ‹Исходный›s2‹/Исходный› ‹Перевод›a1‹/Перевод› ‹Уровень›0‹/Уровень› ‹/Word›‹?xml version=1.0 encoding=utf-8?› ‹Word xmlns:xsi=w3.org/2001/XMLSchema-instance xmlns:xsd=w3.org/2001/XMLSchema› ‹Native›s2‹/Native› ‹Translation›a2‹/Translation› ‹Level ›0‹/Уровень› ‹/Word›‹?xml версия=1.0 кодировка=utf-8?›   -  person BuahahaXD    schedule 25.12.2012
comment
Это неправильно сформированный XML (обратите внимание на несколько объявлений XML). Этот XML все равно не будет десериализоваться.   -  person Kenneth K.    schedule 25.12.2012


Ответы (2)


Прежде всего, вы не должны сериализовать каждое слово по одному. Это приведет к тому, что один файл будет содержать множество XML-файлов, что, конечно же, будет недопустимым.

Вы хотите сериализовать Words (то есть List<Word>) . Поэтому ваше создание сериализатора должно быть new XmlSerializer(typeof(List<Word>)), а сериализация - writer.Serialize(file, Words);.

Таким образом, ваш код может быть таким:

List<Word> Words = ........

WriteXML("a.xml", Words);
var newWords = ReadXML<List<Word>>("a.xml");

public static void WriteXML(string fileName,object obj)
{
    using (var f = File.Create(fileName))
    {
        XmlSerializer ser = new XmlSerializer(obj.GetType());
        ser.Serialize(f, obj);
    }
}

public static T ReadXML<T>(string fileName)
{
    using (var f = File.Open(fileName,FileMode.Open,FileAccess.Read))
    {
        XmlSerializer ser = new XmlSerializer(typeof(T));
        return (T)ser.Deserialize(f);
    }
}

PS: атрибут Serializable требуется только для BinaryFormatter. XmlSerializer в этом не нуждается.

Подробнее об атрибутах, которые XmlSerializer использует здесь

person L.B    schedule 25.12.2012

Как вы можете сериализовать отдельный объект Word в один и тот же файл? Это своего рода переопределение файла на каждой итерации. Просто сериализуйте объект Database вместо отдельных объектов Word следующим образом:

System.Xml.Serialization.XmlSerializer writer =
    new System.Xml.Serialization.XmlSerializer(typeof(Database));
System.IO.StreamWriter file = new System.IO.StreamWriter(fileName);
writer.Serialize(file, yourDatabaseObject);

Примечание. Кроме того, убедитесь, что Database помечен атрибутом Serializable.

person Furqan Safdar    schedule 25.12.2012
comment
В моем коде есть класс Word и класс базы данных, который имеет свойство: public static List‹Word› Words { get; набор; }. Нужно ли мне создавать новый класс, чтобы пометить Word как [Serializable]? Или я должен пометить базу данных этим атрибутом? - person BuahahaXD; 25.12.2012
comment
В этом случае лучше использовать класс базы данных, поскольку вы не можете пометить слова как сериализуемые, потому что это свойство. - person Furqan Safdar; 25.12.2012
comment
-1 a) Вы сериализуете Words (то есть List‹Word›), но создаете сериализатор с typeof(Word) b) атрибут Serializable не требуется для XmlSerialization - person L.B; 26.12.2012
comment
@ ŁukaszKastelik, пожалуйста, обновите вопрос, указав также полную информацию об объекте базы данных. О чем вы упомянули в комментариях. - person Furqan Safdar; 26.12.2012