Skip to content

Instantly share code, notes, and snippets.

@frankmeola
Last active August 24, 2022 10:11
Show Gist options
  • Save frankmeola/9500038 to your computer and use it in GitHub Desktop.
Save frankmeola/9500038 to your computer and use it in GitHub Desktop.
A simple XML minifier in C#.
using System.IO;
using System.Text;
using System.Xml;
namespace XMLMinifier
{
/// <summary>
/// Config object for the XML minifier.
/// </summary>
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
};
}
}
}
/// <summary>
/// XML minifier. No Regex allowed! ;-)
///
/// Example)
/// var sampleXml = File.ReadAllText("somefile.xml");
/// var minifiedXml = new XMLMinifier(XMLMinifierSettings.Aggressive).Minify(sampleXml);
/// </summary>
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());
}
}
}
}
@riccardo1993
Copy link

Hi, it's not a good practice to use the same name for the class and namespace, everything else is OK.

bye

@ITJoePC
Copy link

ITJoePC commented Jul 11, 2019

This is a useful example without RegEx and I will try to achieve similar with XDocument.Parse(). Thanks!

@frankmeola
Copy link
Author

Thanks. Glad it is useful!

@suprannette
Copy link

suprannette commented Sep 23, 2019

Hi,
Is it possible to not add the encoding with parameters ?
Thank you :)

@Vikas-jk
Copy link

Good work, We have created online XML formatter, built in C#.
Will definitely add more tool on website using above functionality to minify XML, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment