Xml serialization - Hide null values

C#.NetXml Serialization

C# Problem Overview


When using a standard .NET Xml Serializer, is there any way I can hide all null values? The below is an example of the output of my class. I don't want to output the nullable integers if they are set to null.

Current Xml output:

<?xml version="1.0" encoding="utf-8"?>
<myClass>
   <myNullableInt p2:nil="true" xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" />
   <myOtherInt>-1</myOtherInt>
</myClass>

What I want:

<?xml version="1.0" encoding="utf-8"?>
<myClass>
   <myOtherInt>-1</myOtherInt>
</myClass>

C# Solutions


Solution 1 - C#

You can create a function with the pattern ShouldSerialize{PropertyName} which tells the XmlSerializer if it should serialize the member or not.

For example, if your class property is called MyNullableInt you could have

public bool ShouldSerializeMyNullableInt() 
{
  return MyNullableInt.HasValue;
}

Here is a full sample

public class Person
{
  public string Name {get;set;}
  public int? Age {get;set;}
  public bool ShouldSerializeAge()
  {
    return Age.HasValue;
  }
}

Serialized with the following code

Person thePerson = new Person(){Name="Chris"};
XmlSerializer xs = new XmlSerializer(typeof(Person));
StringWriter sw = new StringWriter();
xs.Serialize(sw, thePerson);

Results in the followng XML - Notice there is no Age

<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Chris</Name>
</Person>

Solution 2 - C#

Additionally to what Chris Taylor wrote: if you have something serialized as an attribute, you can have a property on your class named {PropertyName}Specified to control if it should be serialized. In code:

public class MyClass
{
    [XmlAttribute]
    public int MyValue;

    [XmlIgnore]
    public bool MyValueSpecified;
}

Solution 3 - C#

It exists a property called XmlElementAttribute.IsNullable

If the IsNullable property is set to true, the xsi:nil attribute is generated for class members that have been set to a null reference.

The following example shows a field with the XmlElementAttribute applied to it, and the IsNullable property set to false.

public class MyClass
{
   [XmlElement(IsNullable = false)]
   public string Group;
}

You can have a look to other XmlElementAttribute for changing names in serialization etc.

Solution 4 - C#

You can define some default values and it prevents the fields from being serialized.

    [XmlElement, DefaultValue("")]
    string data;

    [XmlArray, DefaultValue(null)]
    List<string> data;

Solution 5 - C#

I prefer creating my own xml with no auto-generated tags. In this I can ignore creating the nodes with null values:

public static string ConvertToXML<T>(T objectToConvert)
    {
        XmlDocument doc = new XmlDocument();
        XmlNode root = doc.CreateNode(XmlNodeType.Element, objectToConvert.GetType().Name, string.Empty);
        doc.AppendChild(root);
        XmlNode childNode;

        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
        foreach (PropertyDescriptor prop in properties)
        {
            if (prop.GetValue(objectToConvert) != null)
            {
                childNode = doc.CreateNode(XmlNodeType.Element, prop.Name, string.Empty);
                childNode.InnerText = prop.GetValue(objectToConvert).ToString();
                root.AppendChild(childNode);
            }
        }            

        return doc.OuterXml;
    }

Solution 6 - C#

In my case the nullable variables/elements were all String type. So, I simply performed a check and assigned them string.Empty in case of NULL. This way I got rid of the unnecessary nil and xmlns attributes (p3:nil="true" xmlns:p3="http://www.w3.org/2001/XMLSchema-instance)

// Example:

myNullableStringElement = varCarryingValue ?? string.Empty

// OR

myNullableStringElement = myNullableStringElement ?? string.Empty

Solution 7 - C#

private static string ToXml(Person obj)
{
  XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
  namespaces.Add(string.Empty, string.Empty);

  string retval = null;
  if (obj != null)
  {
    StringBuilder sb = new StringBuilder();
    using (XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings() { OmitXmlDeclaration = true }))
    {
      new XmlSerializer(obj.GetType()).Serialize(writer, obj,namespaces);
    }
    retval = sb.ToString();
  }
  return retval;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGuruMeditationView Question on Stackoverflow
Solution 1 - C#Chris TaylorView Answer on Stackoverflow
Solution 2 - C#Daniel RoseView Answer on Stackoverflow
Solution 3 - C#JPBlancView Answer on Stackoverflow
Solution 4 - C#MichaelSoView Answer on Stackoverflow
Solution 5 - C#Durga NunnaView Answer on Stackoverflow
Solution 6 - C#SagarView Answer on Stackoverflow
Solution 7 - C#RauldView Answer on Stackoverflow