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!