De-serialize whitespace characters using IXmlSerializable

Sometimes back I faced an issue where the customer was trying to de-serialize whitespace characters. Pretty innocuous from the look of it – why will someone try to de-serialize and preserve white space characters? Naïve – there is a reason for everything. Nonetheless it took me quite a while to figure out the resolution.

Let’s take the following type definition as an example:

public class FooClass

    {

      private string _someName;

        private string _someValue;

        public FooClass()

        { }

        [System.Xml.Serialization.XmlText()]

        public string SomeName

        {

            get

            {

                return this._someName;

            }

            set

            {

                this._someName = value;

            }

        }

        public string SomeValue

        {

            get

            {

                return this._someValue;

            }

            set

            {

                this._someValue = value;

            }

        }

            }

Let’s say we are trying to de-serialize the following input xml file:

            <?xml version="1.0" encoding="utf-8"?>

<FooClass xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema">

      <SomeName> </SomeName>

  <SomeValue>some value</SomeValue>

</FooClass>

If you try to de-serialize this using XmlSerializer.Deserialize() method, the resultant type will content the following values :

             this.SomeName = “” //the whitespace characters are eliminated

                        this.SomeValue = “some value”

 

Even using XmlTextReader with WhitespaceHandling property set to WhiteSpaceHandling.All will not help in this case. The magic is to implement IXmlSerializable while defining the type:

 

            #region IXmlSerializable Members

public System.Xml.Schema.XmlSchema GetSchema()

      {

      return null;

      }

      public void ReadXml(XmlReader reader)

      {

      string xmlContent = reader.ReadOuterXml();

            XmlDocument doc = new XmlDocument();

            doc.PreserveWhitespace = true;

            doc.LoadXml(xmlContent);

           XmlNodeList list = doc.DocumentElement.ChildNodes;

            foreach (XmlNode node in list)

            {

                if (node.Name.Equals("SomeName"))

                    this.SomeName = node.InnerXml;

                else if (node.Name.Equals("SomeValue"))

                    this.SomeValue = node.InnerXml;

            }

      }

      public void WriteXml(XmlWriter writer)

      {

            writer.WriteStartElement("SomeName");

            writer.WriteString(this.SomeName);

            writer.WriteEndElement();

            writer.WriteStartElement("SomeValue");

            writer.WriteString(this.SomeValue);

            writer.WriteEndElement();

      }

      #endregion

One of the most important things that you should take care of is setting the “PreserveWhitespace” property of the XmlDocument object. Or else, the whitespaces will be eliminated while loading into XmlDocument.The rest of the implementation code is pretty straight forward.