C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
New: The new StringWriter is required for the HtmlTextWriter to write to. It is a buffer and everything that is written is written to this.
StringWriterMethods: We need to use "RenderBegin" and "RenderEnd" methods. Call RenderBeginTag to open a new level in the HTML with that tag.
And: You must manually close that level of that markup with RenderEndTag. These two methods must be called in pairs.
Attributes: Add the attribute with AddAttribute before BeginRenderTag. Look for "HtmlTextWriterAttribute.Class" and similar.
C# program that uses HtmlTextWriter
using System;
using System.IO;
using System.Web.UI;
class Program
{
    static string[] _words = { "Sam", "Dot", "Perls" };
    static string GetDivElements()
    {
        // Initialize StringWriter instance.
        StringWriter stringWriter = new StringWriter();
        // Put HtmlTextWriter in using block because it needs to call Dispose.
        using (HtmlTextWriter writer = new HtmlTextWriter(stringWriter))
        {
            // Loop over some strings.
            foreach (var word in _words)
            {
                // Some strings for the attributes.
                string classValue = "ClassName";
                string urlValue = "http://www.dotnetCodex.com/";
                string imageValue = "image.jpg";
                // The important part:
                writer.AddAttribute(HtmlTextWriterAttribute.Class, classValue);
                writer.RenderBeginTag(HtmlTextWriterTag.Div); // Begin #1
                writer.AddAttribute(HtmlTextWriterAttribute.Href, urlValue);
                writer.RenderBeginTag(HtmlTextWriterTag.A); // Begin #2
                writer.AddAttribute(HtmlTextWriterAttribute.Src, imageValue);
                writer.AddAttribute(HtmlTextWriterAttribute.Width, "60");
                writer.AddAttribute(HtmlTextWriterAttribute.Height, "60");
                writer.AddAttribute(HtmlTextWriterAttribute.Alt, "");
                writer.RenderBeginTag(HtmlTextWriterTag.Img); // Begin #3
                writer.RenderEndTag(); // End #3
                writer.Write(word);
                writer.RenderEndTag(); // End #2
                writer.RenderEndTag(); // End #1
            }
        }
        // Return the result.
        return stringWriter.ToString();
    }
    static void Main()
    {
        // Demonstrate HtmlTextWriter.
        Console.WriteLine(GetDivElements());
    }
}
Output
<div class="ClassName">
        <a href="http://www.dotnetCodex.com/">
        <img src="image.jpg" width="60" height="60" alt="" />Sam</a>
</div><div class="ClassName">
        <a href="http://www.dotnetCodex.com/">
        <img src="image.jpg" width="60" height="60" alt="" />Dot</a>
</div><div class="ClassName">
        <a href="http://www.dotnetCodex.com/">
        <img src="image.jpg" width="60" height="60" alt="" />Perls</a>
</div>
Fragment that uses string.Empty: C#
using (HtmlTextWriter writer = new HtmlTextWriter(stringWriter,
    string.Empty))
{
    // Insert code here.
}
Note: I am not aware of any performance issues. And the markup is always nicely indented.