Proper way to implement IXmlSerializable?

Posted by Greg on Stack Overflow See other posts from Stack Overflow or by Greg
Published on 2008-11-10T23:19:09Z Indexed on 2010/04/19 3:33 UTC
Read the original article Hit count: 534

Once a programmer decides to implement IXmlSerializable, what are the rules and best practices for implementing it? I've heard that GetSchema() should return null and ReadXml should move to the next element before returning. Are these true? And what about WriteXml: should it write a root element for the object or is it assumed that the root is already written? How should child objects be treated and written.

Here's a sample of what I have now. I'll update it as I get good responses.

public class Calendar: IEnumerable<Gvent>, IXmlSerializable
{
    public XmlSchema GetSchema() { return null; }

    public void ReadXml(XmlReader reader)
    {
        if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "Calendar")
        {
            _Name = reader["Name"];
            _Enabled = Boolean.Parse(reader["Enabled"]);
            _Color = Color.FromArgb(Int32.Parse(reader["Color"]));

            if (reader.ReadToDescendant("Event"))
            {
                while (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "Event")
                {
                    var evt = new Event();
                    evt.ReadXml(reader);
                    _Events.Add(evt);
                }
            }
            reader.Read();
        }
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteAttributeString("Name", _Name);
        writer.WriteAttributeString("Enabled", _Enabled.ToString());
        writer.WriteAttributeString("Color", _Color.ToArgb().ToString());

        foreach (var evt in _Events)
        {
            writer.WriteStartElement("Event");
            evt.WriteXml(writer);
            writer.WriteEndElement();
        }
    }
}

public class Event : IXmlSerializable
{
    public XmlSchema GetSchema() { return null; }

    public void ReadXml(XmlReader reader)
    {
        if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "Event")
        {
            _Title = reader["Title"];
            _Start = DateTime.FromBinary(Int64.Parse(reader["Start"]));
            _Stop = DateTime.FromBinary(Int64.Parse(reader["Stop"]));
            reader.Read();
        }
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteAttributeString("Title", _Title);
        writer.WriteAttributeString("Start", _Start.ToBinary().ToString());
        writer.WriteAttributeString("Stop", _Stop.ToBinary().ToString());
    }
}

© Stack Overflow or respective owner

Related posts about c#

Related posts about Xml