Simple XML minifier in C#

C# .NET language

In this new post, I give you my code for a simple XML minifier in C#. I know I always have strange thought but I’m a developer…

So, I was working on a new component for Blazor for displaying icons and flags. The SVG images are a list of command for drawing a picture in a XML style. As every other XML, the code is indented. So, as humans we can read better the code.

In my specific case, I want to have for each image a string and create a class with all the icons code in SVG (if it is not clear what I mean, see the post).

The source code of this project is on GitHub. Please leave your comment below or use my forum.

XMLMinifierSettings

First, I create the class for settings and I define 4 properties for that. Then, I add 2 common settings: Aggressive to reduce as much as possible the XML and NoMinification that leave the XML as it is. You can create your own settings as you like.

public class XMLMinifierSettings
{
    public bool RemoveEmptyLines { get; set; }
    public bool RemoveWhitespaceBetweenElements { get; set; }
    public bool CloseEmptyTags { get; set; }
    public bool RemoveComments { get; set; }

    public static XMLMinifierSettings Aggressive
    {
        get
        {
            return new XMLMinifierSettings
            {
                RemoveEmptyLines = true,
                RemoveWhitespaceBetweenElements = true,
                CloseEmptyTags = true,
                RemoveComments = true
            };
        }
    }

    public static XMLMinifierSettings NoMinification
    {
        get
        {
            return new XMLMinifierSettings
            {
                RemoveEmptyLines = false,
                RemoveWhitespaceBetweenElements = false,
                CloseEmptyTags = false,
                RemoveComments = false
            };
        }
    }
}

XMLMinifier

Now, the important part. The class XMLMinifier has a function Minify to organize the XML based on the settings.

public class XMLMinifier
{
    private XMLMinifierSettings _minifierSettings;

    public XMLMinifier(XMLMinifierSettings minifierSettings)
    {
        _minifierSettings = minifierSettings;
    }

    public string Minify(string xml)
    {
        var originalXmlDocument = new XmlDocument();
        originalXmlDocument.PreserveWhitespace = 
            !(_minifierSettings.RemoveWhitespaceBetweenElements || 
                _minifierSettings.RemoveEmptyLines);
        originalXmlDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(xml)));

        //remove comments first so we have less to compress later
        if (_minifierSettings.RemoveComments)
        {
            foreach (XmlNode comment in originalXmlDocument.SelectNodes("//comment()"))
            {
                comment.ParentNode.RemoveChild(comment);
            }
        }

        if (_minifierSettings.CloseEmptyTags)
        {
            foreach (XmlElement el in 
                originalXmlDocument.SelectNodes("descendant::*[not(*) and not(normalize-space())]"))
            {
                el.IsEmpty = true;
            }
        }

        if (_minifierSettings.RemoveWhitespaceBetweenElements)
        {
            return originalXmlDocument.InnerXml;
        }
        else
        {
            var minified = new MemoryStream();
            originalXmlDocument.Save(minified);

            return Encoding.UTF8.GetString(minified.ToArray());
        }
    }
}

Example

Finally, a simple example how to use the code above. For the path folder, the console app reads the list of SVG file. Then, it sets the XMLMinifier. So, for each file it runs the Minify, remove the SVG tag and save the result string in a new file ending with .min.svg

using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using XMLMinimizer;

string path = @"C:\Users\enric\OneDrive\Desktop\fileToConvert";
DirectoryInfo d = new DirectoryInfo(path); //Assuming Test is your Folder

FileInfo[] Files = d.GetFiles("*.svg"); //Getting Text files

var xmlMin = new XMLMinifier(XMLMinifierSettings.Aggressive);
string code = "";

foreach (FileInfo file in Files)
{
    string text = System.IO.File.ReadAllText(file.FullName);
    string minText = xmlMin.Minify(text);
    string rsl = Regex.Replace(minText, "</?(svg|SVG).*?>", "", RegexOptions.IgnoreCase);
    rsl = rsl.Replace("\"", "'");

    string result = Path.GetFileNameWithoutExtension(file.FullName) + ".min" + 
                    Path.GetExtension(file.FullName);
    File.WriteAllText(Path.Combine(path, result), rsl);
}

Wrap up

In conclusion, this is the code for a simple XML minifier in C#. I hope you like and it could be useful for you.

Happy coding!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.