Proper use of the IXmlSerializable Interface.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Airslash
    New Member
    • Nov 2007
    • 221

    #1

    Proper use of the IXmlSerializable Interface.

    Hello,

    I'm currently struggeling a bit with the Serialization aspects of the .NET framework. The Binary serialization is no problem, works relatively easy and is easy to implement. It's the XML serialization that's causing me problems at the moment.

    I've been trying to sniff through the MSDN documentation regarding the IXmlSerializabl e itnerface, but the documentation is "lacking" at best...

    So i've come up with the following implementation at the moment:

    Code:
    public System.Xml.Schema.XmlSchema GetSchema()
            {
                // Not used in the .NET environment anymoe.
                return null;
            }
    Code:
    /// <summary>
            /// This function is called by the XmlReader when the object is beeing 
            /// deserialized from the Xml file. This function assigns all the values
            /// back to the datamembers.
            /// </summary>
            /// <param name="reader">The XmlReader containing all the information.</param>
            public void ReadXml(System.Xml.XmlReader reader)
            {
                // First consume the XML element, since we don't need this.
                reader.ReadStartElement();
                
                // Open the root element of our class so we can retrieve the info.
                reader.ReadStartElement("Database");
                
                // Read out each individual element using our private wrapper function.
                m_command = ReadElement<IDbCommand>("Command", reader);
                m_connection = ReadElement<IDbConnection>("Connection", reader);
                m_transport = ReadElement<Transport>("Transport", reader);
                m_port = ReadElement<uint>("Port", reader);
                m_server = ReadElement<string>("Server", reader);
                m_ip = ReadElement<string>("IpAddress", reader);
                m_name = ReadElement<string>("Name", reader);
                m_compression = ReadElement<uint>("Compression", reader);
                m_blockreadsize = ReadElement<int>("BlockReadSize", reader);
                m_username = ReadElement<string>("Username", reader);
                m_password = ReadElement<string>("Password", reader);
    
                // Close the root element for our database.
                reader.ReadEndElement();
    
                // Close the final xml element.
                reader.ReadEndElement();
            }
    Code:
    public void WriteXml(System.Xml.XmlWriter writer)
            {
                // Write out all our internal datamembers.
                // We do not have to write the root xml element, that's for the caller.
                // So first we write the root element from our class.
                writer.WriteStartElement("Database");
    
                // Since we don't have to write any attributes we can now write out
                // each element individually.
                WriteElement("Command", m_command, writer);
                WriteElement("Connection", m_connection, writer);
                WriteElement("Transport", m_transport, writer);
                WriteElement("Port", m_port, writer);
                WriteElement("Server", m_server, writer);
                WriteElement("IpAddress", m_ip, writer);
                WriteElement("Name", m_name, writer);
                WriteElement("Compression", m_compression, writer);
                WriteElement("BlockReadSize", m_blockreadsize, writer);
                WriteElement("Username", m_username, writer);
                WriteElement("Password", m_password, writer);
    
                // Write the closing tag of our class.
                writer.WriteEndElement();
            }
    and two helper function to make the serialization a bit easier for me.
    Code:
            /// <summary>
            /// Reads the specified element from the XmLReader and automaticly
            /// casts it back to the specified type.
            /// </summary>
            /// <typeparam name="T">The type to be returned.</typeparam>
            /// <param name="name">The name of the element to be read.</param>
            /// <param name="reader">The reader to read the element from.</param>
            /// <returns>The value from the reader cast to type T</returns>
            private T ReadElement<T>(string name, System.Xml.XmlReader reader)
            {
                reader.ReadStartElement(name);                      // Open the element.
                return (T)reader.ReadContentAs(typeof(T), null);    // Read and cast the value.
                reader.ReadEndElement();                            // Close the element.
            }
    
            /// <summary>
            /// Writes the specified element in the XmlWriter and automaticly creates
            /// the openening and closing tag for the element.
            /// This function writes the specified element without attributes.
            /// </summary>
            /// <param name="name">The name of the Element to write</param>
            /// <param name="value">The value of the Element</param>
            /// <param name="writer">The write to write the element to.</param>
            private void WriteElement(string name, object value, System.Xml.XmlWriter writer)
            {
                writer.WriteStartElement(name);
                writer.WriteValue(value);
                writer.WriteEndElement();
            }
    The class is called database and has a bunch of private members that I want serialized. I'm not entirely sure if this is the way to go, but the documentation around this is bad.....
    I know it can be done automaticly by just adding the attributes in the class such as [XmlRoot], but I wanted to work with the Interface...
Working...