XML Serialization Helpers

public static class Serialization {
    private static readonly Encoding _defaultEncoding = Encoding.UTF8;

    public static T DeserializeXmlFile<T>(string fileName) {
        if (!File.Exists(fileName))
            throw new FileNotFoundException();

        var serializer = new XmlSerializer(typeof(T));
        using (var xmlReader = new XmlTextReader(fileName)) {
            return (T)serializer.Deserialize(xmlReader);
        }
    }

    public static T Deserialize<T>(TextReader textReader) {
        if (textReader == null)
            throw new ArgumentNullException("textReader");

        var serializer = new XmlSerializer(typeof(T));
        return (T)(serializer.Deserialize(textReader));
    }

    public static T Deserialize<T>(string serializedObject) {
        if (string.IsNullOrEmpty(serializedObject))
            return default(T);

        var serializer = new XmlSerializer(typeof(T));
        using (var objectReader = new StringReader(serializedObject)) {
            return (T)serializer.Deserialize(objectReader);
        }
    }

    public static void SerializeToXmlFile<T>(T objectToSerialize, string fileName) {
        SerializeToXmlFile(objectToSerialize, fileName, _defaultEncoding);
    }

    public static void SerializeToXmlFile<T>(T objectToSerialize, string fileName, Encoding encoding) {
        var serializer = new XmlSerializer(typeof(T));
        using (var xmlWriter = new XmlTextWriter(fileName, encoding) { Formatting = Formatting.Indented, IndentChar = '\t', Indentation = 1 }) {
            serializer.Serialize(xmlWriter, objectToSerialize);
        }
    }

    public static string Serialize<T>(T objectToSerialize, bool includeXmlDeclaration, bool indent) {
        var serializer = new XmlSerializer(typeof(T));
        var sb = new StringBuilder(0x1000);

        XmlTextWriter xmlWriter =
            includeXmlDeclaration
            ? new XmlTextWriter(new StringWriter(sb))
            : new XmlTextWriterWithoutDeclaration(new StringWriter(sb));

        if (indent) {
            xmlWriter.Formatting = Formatting.Indented;
            xmlWriter.IndentChar = '\t';
            xmlWriter.Indentation = 1;
        }

        var namespaces = new XmlSerializerNamespaces();
        namespaces.Add(string.Empty, string.Empty);
        serializer.Serialize(xmlWriter, objectToSerialize, namespaces);
        return sb.ToString();
    }

    private class XmlTextWriterWithoutDeclaration
        : XmlTextWriter
    {
        public XmlTextWriterWithoutDeclaration(TextWriter w)
            : base(w)
        { }

        public override void WriteStartDocument() { }

        public override void WriteStartDocument(bool standalone) { }
    }
}

These are just a few helpers to make using the built-in XmlSerializer a little bit easier. It skips the needless XML namespaces, which just ugly up simple XML. If you want to skip the <?xml version="1.0" encoding="utf-16"?> declaration, then you can use that overload.

[Serializable] public class Foo { public string Name { get; set; } public int Age { get; set; }

var foo = new Foo { Name = "john", Age = 34 };
string xml = Serialization.Serialize(foo, true, false); // Keep declaration
Console.WriteLine(xml);
Console.WriteLine();
xml = Serialization.Serialize(foo, false, false); // Remove declaration
Console.WriteLine(xml);
Console.WriteLine();
using (var writer = new StringWriter())
{
    new XmlSerializer(typeof(Foo)).Serialize(writer, foo); // Default serialization
    Console.WriteLine(writer.ToString());
}

Output:

<?xml version="1.0" encoding="utf-16"?><Foo><Name>john</Name><Age>34</Age></Foo>

<Foo><Name>john</Name><Age>34</Age></Foo>

<?xml version="1.0" encoding="utf-16"?>
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>john</Name>
  <Age>34</Age>
</Foo>

Select large text blocks in SSMS

If you have a large string, possibly with line breaks, it may be difficult to read this in SSMS – there are ways to do it, or you can do it outside the editor, but if you’re looking for something quick and dirty to let you analyze text, throw your text into a variable and call the following – the result will be a clickable XML value, with the text inside a CDATA element.

create procedure util.SelectStringAsCdata
(
    @text varchar(max)
)
as
begin
    -- This creates a clickable XML result which opens a new tab in SSMS, allowing you to see
    -- a large text value. PRINT and RAISERROR have limitations, but this will show any
    -- size result.

    declare @crlf char(2) = char(13) + char(10);
    select 1 [TAG], 0 [PARENT], @crlf + @text + @crlf [root!1!!CDATA] for xml explicit;
end;
go

I was hoping to build a function that returns XML, so you could select text like this in a regular query, but apparently SQL Server does not keep CDATA in XML values.

Remove declaration and namespaces from XML serializer

Out of the box, .NET XML serialization is loaded with garbage that I personally never want. It’s one of the reasons I use JSON instead of XML whenever possible.

But one quick way to remove the junk, assuming you’re dealing with simple data, and don’t care about things like encoding or namespaces or whatever, is to just apply a few settings.

Given the following out-of-the-box code:

var foo = new Foo { Name = "John Doe", Age = 34 };
using (var writer = XmlWriter.Create(Console.Out)) {
    new XmlSerializer(typeof (Foo)).Serialize(writer, foo);
}

The console will see the following (aside from the indentation):

<?xml version="1.0" encoding="Codepage - 437"?>
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Name>John Doe</Name>
    <Age>34</Age>
</Foo>

Add a little bit of configuration to the code, and you get something much nicer:

var ns = new XmlSerializerNamespaces(); ns.Add("", "");
var settings = new XmlWriterSettings { OmitXmlDeclaration = true };
using (var writer = XmlWriter.Create(Console.Out, settings)) {
    new XmlSerializer(typeof (Foo)).Serialize(writer, foo, ns); 
}
<Foo>
  <Name>John Doe</Name>
  <Age>34</Age>
</Foo>

Fluent XML writer

Writing XML in .NET is not too terrible, but it sometimes is a bit tricky and lengthy.

A few years ago, I put this library together to write XML easily, using fluent techniques.

Sample Code

static void Main(string[] args) {
    FluentXmlWriter.Start("root")
        .Simple("First")
        .Simple("Second").Attr("a", "b")
        .Complex("Arr")
            .ManySimple(
                SimpleElement.Create("Arr1").Attr("key1", "val1"),
                SimpleElement.Create("Arr2").Attr("key2", "val2")
            ).EndElem()
        .Complex("Third").Text("My Text").EndElem()
        .Complex("Fourth").CData("Hello there!").EndElem()
        .Comment("A comment!")
        .OutputToString(Console.WriteLine);
}

This produces the following output:

<root>
    <First />
    <Second a="b" />
    <Arr>
        <Arr1 key1="val1" />
        <Arr2 key2="val2" />
    </Arr>
    <Third>My Text</Third>
    <Fourth><![CDATA[Hello there!]]></Fourth>
    <!--A comment!-->
</root>

You can download the library here.