Pretty XML in C#

Posted in software by Christopher R. Wirz on Mon Aug 04 2014



XML serialization is a common technique for storing and transacting data objects when programming in C#. While XML produces a file that is human-readable, it is sometimes so mangled that it is hard to understand the data hierarchy.

Luckily, there is an easy way to create an extension method to make XML content pretty. The following code will take an XML string and make apply formatting that makes it easier to read. If the string is not XML, it will simply return the original string.


public static partial class ExtensionMethods
{	
	/// <summary>
	///     Makes XML strings pretty if possible
	/// </summary>
	/// <param name="str">The input string</param>
	/// <param name="settings">The settings for the XML formatting</param>
	/// <returns>A more pretty xml if applicable</returns>
	public static string ToPrettyXml(this string str, XmlWriterSettings settings = null)
	{
		if (string.IsNullOrWhiteSpace(str)) return str;
		try
		{
			XmlDocument xml = new XmlDocument();
			xml.LoadXml(str);

			if (settings == null)
			{
				// Modify these settings to format the XML as desired
				settings = new XmlWriterSettings
				{
					Indent = true,
					NewLineOnAttributes = true,
					Encoding = Encoding.UTF8
				};
			}

			using (StringWriter sw = new StringWriter())
			{
				using (var textWriter = XmlWriter.Create(sw, settings))
				{
					xml.Save(textWriter);
				}
				sw.Flush();
				return sw.ToString();
			}
		}
		catch { }
		return str;
	}
}

Now it is time to try a few tests. The following xml is found in a file called Ugly.xml:


<?xml version="1.0"?>
<Object><Key>0</Key><Children>
<Object><Key>1</Key></Object>
<Object><Lock>5</Lock><Key>2</Key></Object>
<Object><Key>3</Key><Children>
<Object><Key>31</Key></Object>
<Object><Lock>37</Lock><Key>32</Key></Object>
</Children>
</Object></Children></Object>

It is seen that the xml is missing tabs and some carriage returns. This xml hasn't been mangled too much, but it does not exhibit hiarchy. It would be nice to have children indented under their respective parents.

Note: "Pretty" xml may result in a larger file size.

The ToPrettyXml() method is an extension method, so it can be called from any string object. The following code tests the functionality of the ToPrettyXml() method.


class Program
{
	static int Main(string[] args)
	{
		// reads out "this is a test"
		Console.WriteLine("this is a test".ToPrettyXml());

		// reads out nothing
		string str = null;
		Console.WriteLine(str.ToPrettyXml());

		// Make a new file called "Pretty.xml"
		string ugly = File.ReadAllText("Ugly.xml");
		File.WriteAllText("Pretty.xml", ugly.ToPrettyXml());

		Console.ReadKey();
		return 0;
	}
}

Opening the "Pretty.xml" file, the following results are shown.


<?xml version="1.0" encoding="utf-16"?>
<Object>
  <Key>0</Key>
  <Children>
    <Object>
      <Key>1</Key>
    </Object>
    <Object>
      <Lock>5</Lock>
      <Key>2</Key>
    </Object>
    <Object>
      <Key>3</Key>
      <Children>
        <Object>
          <Key>31</Key>
        </Object>
        <Object>
          <Lock>37</Lock>
          <Key>32</Key>
        </Object>
      </Children>
    </Object>
  </Children>
</Object>

XmlWriter has successfully been used to create pretty xml from a given string. To include the functionality of ToPrettyXml(), a using declaration must be made to reference the namespace of the ExtensionMethods class.