Реализация IXmlSerializable для классов, содержащих коллекции - PullRequest
4 голосов
/ 05 июня 2009

Мне нужно иметь возможность сериализировать класс Xml, который является внутренним, поэтому я должен реализовать IXmlSerializable.

Этот класс содержит две строки и список List.

Я знаю, чтобы читать и писать строки, используя WriteElementString & ReadElementContentAsString.

Тем не менее, я заблудился о том, как читать и писать список в методах ReadXml и WriteXml.

Как мне это сделать, или есть ли способ сериализации и десериализации объекта при сохранении его внутренней доступности?

1 Ответ

8 голосов
/ 05 июня 2009

Просто напишите элемент <List> для самого списка, затем зациклите элементы и запишите их как <Item> элементы.

Если элементы являются экземплярами класса, который можно сериализовать в формате XML, вы можете создать экземпляр XmlSerializer для типа элемента, а затем просто сериализовать каждый из них в тот же XmlWriter, который вы уже используете. Пример:


public void WriteXml(XmlWriter writer)
{
    writer.WriteStartElement("XmlSerializable");

    writer.WriteElementString("Integer", Integer.ToString());

    writer.WriteStartElement("OtherList");
    writer.WriteAttributeString("count", OtherList.Count.ToString());

    var otherSer = new XmlSerializer(typeof(OtherClass));
    foreach (var other in OtherList)
    {
        otherSer.Serialize(writer, other);
    }
    writer.WriteEndElement();

    writer.WriteEndElement();
}

public void ReadXml(XmlReader reader)
{
    reader.ReadStartElement("XmlSerializable");

    reader.ReadStartElement("Integer");
    Integer = reader.ReadElementContentAsInt();
    reader.ReadEndElement();

    reader.ReadStartElement("OtherList");
    reader.MoveToAttribute("count");
    int count = int.Parse(reader.Value);

    var otherSer = new XmlSerializer(typeof (OtherClass));
    for (int i=0; i<count; i++)
    {
        var other = (OtherClass) otherSer.Deserialize(reader);
        OtherList.Add(other);
    }

    reader.ReadEndElement();
    reader.ReadEndElement();
}
...