I\'m serializing a class like this
public MyClass
{
public int? a { get; set; }
public int? b { get; set; }
public int? c { get; set; }
}
This question's been asked quite a long time ago but still is VERY relevant even in 2017. None of the proposed answers here weren't satisfactory to me so here's a simple solution I came up with:
Using regular expressions is the key. Since we haven't much control over the XmlSerializer's behavior, so let's NOT try to prevent it from serializing those nullable value types. Instead, just take the serialized output and replace the unwanted elements with an empty string using Regex. The pattern used (in C#) is:
<\w+\s+\w+:nil="true"(\s+xmlns:\w+="http://www.w3.org/2001/XMLSchema-instance")?\s*/>
Here's an example:
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Serialization;
namespace MyNamespace
{
///
/// Provides extension methods for XML-related operations.
///
public static class XmlSerializerExtension
{
///
/// Serializes the specified object and returns the XML document as a string.
///
/// The object to serialize.
/// The referenced by the object.
/// An XML string that represents the serialized object.
public static string Serialize(this object obj, XmlSerializerNamespaces namespaces = null)
{
var xser = new XmlSerializer(obj.GetType());
var sb = new StringBuilder();
using (var sw = new StringWriter(sb))
{
using (var xtw = new XmlTextWriter(sw))
{
if (namespaces == null)
xser.Serialize(xtw, obj);
else
xser.Serialize(xtw, obj, namespaces);
}
}
return sb.ToString().StripNullableEmptyXmlElements();
}
///
/// Removes all empty XML elements that are marked with the nil="true" attribute.
///
/// The input for which to replace the content.
/// true to make the output more compact, if indentation was used; otherwise, false.
/// A cleansed string.
public static string StripNullableEmptyXmlElements(this string input, bool compactOutput = false)
{
const RegexOptions OPTIONS =
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline;
var result = Regex.Replace(
input,
@"<\w+\s+\w+:nil=""true""(\s+xmlns:\w+=""http://www.w3.org/2001/XMLSchema-instance"")?\s*/>",
string.Empty,
OPTIONS
);
if (compactOutput)
{
var sb = new StringBuilder();
using (var sr = new StringReader(result))
{
string ln;
while ((ln = sr.ReadLine()) != null)
{
if (!string.IsNullOrWhiteSpace(ln))
{
sb.AppendLine(ln);
}
}
}
result = sb.ToString();
}
return result;
}
}
}
I hope this helps.