HtmlSanitizer by Michael Ganss

<PackageReference Include="HtmlSanitizer" Version="8.1.722-beta" />

 HtmlFormatter

HTML5 markup formatter. Identical to HtmlMarkupFormatter except for < and > which are encoded in attribute values.
using AngleSharp.Dom; using AngleSharp.Html; using System.Runtime.CompilerServices; using System.Text; namespace Ganss.Xss { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public class HtmlFormatter { public static readonly HtmlFormatter Instance = new HtmlFormatter(); protected override string Attribute(IAttr attr) { string namespaceUri = attr.get_NamespaceUri(); string localName = attr.get_LocalName(); string value = attr.get_Value(); StringBuilder stringBuilder = new StringBuilder(); if (string.IsNullOrEmpty(namespaceUri)) stringBuilder.Append(localName); else if (namespaceUri == NamespaceNames.XmlUri) { stringBuilder.Append(NamespaceNames.XmlPrefix).Append(':').Append(localName); } else if (namespaceUri == NamespaceNames.XLinkUri) { stringBuilder.Append(NamespaceNames.XLinkPrefix).Append(':').Append(localName); } else if (namespaceUri == NamespaceNames.XmlNsUri) { stringBuilder.Append(HtmlMarkupFormatter.XmlNamespaceLocalName(localName)); } else { stringBuilder.Append(attr.get_Name()); } stringBuilder.Append('=').Append('"'); for (int i = 0; i < value.Length; i++) { switch (value[i]) { case '&': stringBuilder.Append("&amp;"); break; case ' ': stringBuilder.Append("&nbsp;"); break; case '"': stringBuilder.Append("&quot;"); break; case '<': stringBuilder.Append("&lt;"); break; case '>': stringBuilder.Append("&gt;"); break; default: stringBuilder.Append(value[i]); break; } } return stringBuilder.Append('"').ToString(); } public HtmlFormatter() : this() { } } }