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!