ShouldSerialize - Conditional XML Serialization using C# with example

Sep 10, 2013

In case you are serializing your models to generate XML content, you will often encounter empty nodes and elements in the XML which appears when the entity property is not filled or the list is empty.

Lets take an example of Employee model class as below:

using System.Collections.Generic;
using System.Xml.Serialization;

public class Employee
{
    public Employee()
    {
        this.Skills = new List<string>();
    }

    [XmlElement("FirstName")]
    public string FirstName { get; set; }

    [XmlElement("LastName")]
    public string LastName { get; set; }
    
    [XmlArray("Skills")]
    [XmlArrayItem("Skill")]
    public List<string> Skills { get; set; }
}

When you generate XML for the above model by assigning FirstName and LastName only keeping Skills empty:

var employeeDetail = new Employee() { FirstName = "Mister", LastName = "XYZ" };
var employeeDetailXml = SerializeXml(employeeDetail);

you will get XML content something like this:

<?xml version="1.0" encoding="utf-16"?>
<Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <FirstName>Mister</FirstName>
  <LastName>XYZ</LastName>
  <Skills />
</Employee>

Here you can see Skills node is empty and in some case you may want it to be ignored when generating XML so that you do not get any empty nodes or elements.

This can be done by creating method with specific prefix ShouldSerialize followed by XML element / property name (exactly same) and return boolean value based on calculations or check you need to perform to decide if the element will be null or empty and whether to include it in the XML or not.

Thus the Employee model with ShouldSerialize implementation for Skills property will look something like below:

using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;

////[Serializable]
[XmlRoot("Employee")]
public sealed class EmployeeWithShouldSerialize
{
    public EmployeeWithShouldSerialize()
    {
        this.Skills = new List&lt;string&gt;();
    }

    [XmlElement("FirstName")]
    public string FirstName { get; set; }
    
    [XmlElement("LastName")]
    public string LastName { get; set; }

    [XmlArray("Skills")]
    [XmlArrayItem("Skill")]
    public List&lt;string&gt; Skills { get; set; }

    public bool ShouldSerializeSkills()
    {
        return null != this.Skills &amp;&amp; this.Skills.Any();
    }
}

The ShouldSerializeSkills method will return false if the Skills list is empty or null or does not any any element.

Now if we serialize the model and generate XML for the same as follows:

var employeeDetailWithShouldSerialize = new EmployeeWithShouldSerialize { FirstName = "Mister", LastName = "ABC" };
var employeeDetailWithShouldSerializeXml = SerializeXml(employeeDetailWithShouldSerialize);

Now you will get XML which will not have the empty Skills element / node:

<?xml version="1.0" encoding="utf-16"?>
<Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <FirstName>Mister</FirstName>
  <LastName&gt;ABC&lt;/LastName>
</Employee>

You can read more on Using UTF-8 encoding for StringWriter in C#

Sample code on Github for ShouldSerialize - Conditional XML serialization

Download Code

Happy Coding !!