The goal was to write a simple fluent and recursive tag builder.
Simple – means the implementation should be as short as possible.
Fluent – means a fluent interface
Recursive – means that tags could possibly be nested one inside the other.
The implementation is as follows:
public class TagBuilder
{        public TagBuilder() { }    public TagBuilder( string TagName, TagBuilder Parent )
    {            this.tagName = TagName;            this.parent = Parent;    }
private string tagName;
    private TagBuilder    parent;    private StringBuilder body = new StringBuilder();
private Dictionary<string, string> _attributes = new Dictionary<string, string>();
public TagBuilder AddContent( string Content )
    {    body.Append( Content );
return this;
}
public TagBuilder AddContentFormat( string Format, params object[] args )
    {    body.AppendFormat( Format, args );
return this;
}
public TagBuilder StartTag( string TagName )
    {    TagBuilder tag = new TagBuilder( TagName, this );
        return tag;    }
    public TagBuilder EndTag()        {            parent.AddContent( this.ToString() );            return parent;    }
public TagBuilder AddAttribute( string Name, string Value )
    {    _attributes.Add( Name, Value );
return this;
}
public override string ToString()
    {            StringBuilder tag = new StringBuilder();            // preamble    if ( !string.IsNullOrEmpty( this.tagName ) )
            tag.AppendFormat( "<{0}", tagName );            if ( _attributes.Count > 0 )            {                tag.Append( " " );    tag.Append(
string.Join( " ",
_attributes
.Select(
kvp => string.Format( "{0}='{1}'", kvp.Key, kvp.Value ) )
.ToArray() ) );
}
        // body/ending            if ( body.Length > 0 )            {    if ( !string.IsNullOrEmpty( this.tagName) || this._attributes.Count > 0 )
                tag.Append( ">" );    tag.Append( body.ToString() );
if ( !string.IsNullOrEmpty( this.tagName ) )
tag.AppendFormat( "</{0}>", this.tagName );
}
        else    if ( !string.IsNullOrEmpty( this.tagName ) )
                tag.Append( "/>" );            return tag.ToString();    }
}
Example usage:
var script =
 tag.StartTag( "parent" )    .AddAttribute( "parentproperty1", "true" )
.AddAttribute( "parentproperty2", "5" )
         .StartTag( "child1")    .AddAttribute( "childproperty1", "c" )
         .AddContent( "childbody" )    .EndTag()
         .StartTag( "child2" )    .AddAttribute( "childproperty2", "c" )
         .AddContent( "childbody" )    .EndTag()
.EndTag()
     .StartTag( "script" )         .AddContent( "$.scriptbody();")    .EndTag()
.ToString();
Note that I can nest the hierarchy plus I can have two or more tags one beside the other (siblings). The output of this example call is:
<parent parentproperty1='true' parentproperty2='5'><child1 childproperty1='c'>ch
ildbody</child1><child2 childproperty2='c'>childbody</child2></parent><script>$.
scriptbody();</script>
Feel free to modify the code. An example extension would be to implement indentation.
 
 
4 comments:
how can you produce the following data with the code:
<a>x<b>y</b>x</a>
@liuhongbo: sure you can:
var _example =
tag.StartTag( "a" )
.AddContent( "x" )
.StartTag( "b" )
.AddContent( "y" )
.EndTag()
.AddContent( "x" )
.EndTag()
.ToString();
Great class. Very intuitive way of building HTML on the server side. Thanks for sharing
Post a Comment