C#: conditional XML serialization

(This article is a follow-up on http://maffelu.net/c-xml-serializing/)

Sometimes when you serialize something in XML you get empty elements as the value being serialized is empty. This can be annoying, and sometimes that’s not what your recipient wants. If you, for example, serialize the following class:

namespace XmlSerializationTest
{
    [XmlRoot("person")]
    public class Person
    {
        [XmlElement("age")]
        public int Age { get; set; }
 
        [XmlElement("name")]
        public string Name { get; set; }
 
        [XmlArray("nicks")]
        [XmlArrayItem("nick")]
        public List<string> NickNames { get; set; }
 
        public Person()
        {
            NickNames = new List<string>();
        }
    }
}

If we generate a Person object and don’t add any names to the NickNames list we’ll get the following XML:

<?xml version="1.0" encoding="utf-8"?>
<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://
www.w3.org/2001/XMLSchema">
  <age>47</age>
  <name>John Doe</name>
  <nicks />
</person>

Notice how ‘nicks’ is just an empty element. Your recipient is now yelling at you “I don’t want empty elements, remove them if they are empty!” and you’re in a bit of a pickle. How do you remove them? Implement your own serializer? Run a regex on the XML after serialization to remove empty elements?
Well, there is an easier way to handle it. Microsoft has provided optional methods to use known as ShouldSerialize and Reset. I won’t go into Reset in this tutorial but I will show you the use of ShouldSerialize. You create a method called ShouldSerializeX where X is the name of the property to check. This allows for you to add a condition which has to be met for the serialization process to act:

namespace XmlSerializationTest
{
    [XmlRoot("person")]
    public class Person
    {
        [XmlElement("age")]
        public int Age { get; set; }
 
        [XmlElement("name")]
        public string Name { get; set; }
 
        [XmlArray("nicks")]
        [XmlArrayItem("nick")]
        public List<string> NickNames { get; set; }
 
        /// <summary>
        /// Make sure the list of nicknames has any content
        /// </summary>
        public bool ShouldSerializeNickNames()
        {
            return !(NickNames == null || NickNames.Count <= 0);
        }
 
        public Person()
        {
            NickNames = new List<string>();
        }
    }
}

Now if you serialize it you will get this (GenericSerializer was a class we built in the last article mentioned at the start of this post):

Person person = new Person()
{
    Name = "John Doe",
    Age = 47
};
 
string xml = GenericSerializer.Serialize(person);
 
Console.WriteLine(xml);
 
Console.Read();
<?xml version="1.0" encoding="utf-8"?>
<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://
www.w3.org/2001/XMLSchema">
  <age>47</age>
  <name>John Doe</name>
</person>

And with nicknames:

List<string> names = new List<string>();
names.Add("Johnny");
names.Add("J-Man");
Person person = new Person()
{
    Name = "John Doe",
    Age = 47,
    NickNames = names
};
 
string xml = GenericSerializer.Serialize(person);
 
Console.WriteLine(xml);
 
Console.Read();
<?xml version="1.0" encoding="utf-8"?>
<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://
www.w3.org/2001/XMLSchema">
  <age>47</age>
  <name>John Doe</name>
  <nicks>
    <nick>Johnny</nick>
    <nick>J-Man</nick>
  </nicks>
</person>

3 Responses to C#: conditional XML serialization

  1. Pingback: C#: conditional XML serialization | Maffelu.net | XQuery & T-Sql | Scoop.it

  2. Magnus, thank for this post this is exactly what i`am looking for. The simplicity of this solution makes me smile :) ))

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>