How to exclude null properties when using XmlSerializer

前端 未结 9 1814
谎友^
谎友^ 2021-02-02 07:11

I\'m serializing a class like this

public MyClass
{
    public int? a { get; set; }
    public int? b { get; set; }
    public int? c { get; set; }
}
         


        
9条回答
  •  暖寄归人
    2021-02-02 07:45

    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.

提交回复
热议问题