C#实现动态生成静态页面的类详解
本文实例讲述了C#实现动态生成静态页面的类。分享给大家供大家参考,具体如下:
动态生成静态页面有许多好处,比如生成html网页有利于被搜索引擎收录。同时,由于减少了数据访问,减轻对数据库访问的压力,提高了网页打开速度。
基本思路:
使用一个字符串作为页面模板,再页面中包含用若干标志(用{标志名}表示),生成页面时,将标志替换为对应的值。
实现方法:
在初始化TextTemplate实例时读入模板,以标志为分割点将模板分割成几部分,生成页面时只需简单的将模板内容和标志的值连接起来。例如:
假如有一个模板ABCD{TAG1}EFG{TAG2}HIJ{TAG3}KMUN
初始化时将模板分割成"ABCD","EFG","HIJ","KMUN"四个字符串,
假设TAG1=“123”,TAG2=“456”,TAG3=“789”
则生成是相当于执行"ABCD"+"123"+"EFG"+"456"+"HIJ"+"789"+"KMUN"
代码:
usingSystem; usingSystem.Collections.Generic; usingSystem.Text; usingSystem.Text.RegularExpressions; usingSystem.Collections; usingSystem.IO; ///<summary> ///表示一个文本模板,该类使用一个字符串作为模板,通过将模板中的标志替换为对应的值(模板中的标志用{标志名}表示)生成新的文本 ///</summary> ///<example>以下代码用文本模板生成IMG标志 ///<code> ///staticclassProgram ///{ ///[STAThread] ///staticvoidMain() ///{ ///TextTemplatetemp=newTextTemplate("<imgsrc='{src}'alt='{alt}'/>"); ///Console.WriteLine(temp.Render("pic.bmp","Image")); ///Hashtablevalues=newHashtable(); ///values.Add("src","pic.bmp"); ///values.Add("alt","image"); ///Console.WriteLine(temp.Render(values)); ///} ///} /// ///输出为: ///<imgsrc='pic.bmp'alt='Image'/> ///<imgsrc='pic.bmp'alt='image'/> /// ///</code> ///</example> publicclassTextTemplate { TextTemplateTag[]_tags; String[]_contentParts; int_tagCount; privateTextTemplate() { _tagCount=0; _tags=null; _contentParts=null; } ///<summary> ///用指定的模板初始化TextTemplate ///</summary> ///<paramname="content">模板内容</param> publicTextTemplate(Stringcontent) { FromString(content); } ///<summary> ///用指定的模板初始化TextTemplate,模板内容重文件读入 ///</summary> ///<paramname="file">模板文件位置</param> ///<paramname="encoding">文件使用的编码</param> publicTextTemplate(stringfile,Encodingencoding) { StreamReadersr=newStreamReader(file,encoding); try { stringcontent=sr.ReadToEnd(); FromString(content); } catch(Exception) { sr.Close(); throw; } sr.Close(); } ///<summary> ///读入模板并以标志为分割点分割模板 ///</summary> ///<paramname="content"></param> privatevoidFromString(Stringcontent) { MatchCollectionmc=Regex.Matches(content,"{\\w+}"); _tagCount=mc.Count; _tags=newTextTemplateTag[mc.Count]; _contentParts=newstring[mc.Count+1]; intindex=0; foreach(Matchminmc) { _tags[index++]=newTextTemplateTag(m.Value.Substring(1,m.Value.Length-2),m.Index,m.Length); } intstart=0; index=0; foreach(TextTemplateTagconin_tags) { _contentParts[index]=content.Substring(start,con.Position-start); start=con.Position+con.Length; index++; } if(start<content.Length)_contentParts[index]=content.Substring(start); } ///<summary> ///用指定的值生成文本 ///</summary> ///<paramname="values">各标志对应的值(用标志名作为key)</param> ///<returns>生成的文本</returns> ///<example>以下代码用文本模板生成IMG标志 ///<code> ///staticclassProgram ///{ ///[STAThread] ///staticvoidMain() ///{ ///TextTemplatetemp=newTextTemplate("<imgsrc='{src}'alt='{alt}'/>"); ///Console.WriteLine(temp.Render("pic.bmp","Image")); ///Hashtablevalues=newHashtable(); ///values.Add("src","pic.bmp"); ///values.Add("alt","image"); ///Console.WriteLine(temp.Render(values)); ///} ///} /// ///输出为: ///<imgsrc='pic.bmp'alt='Image'/> ///<imgsrc='pic.bmp'alt='image'/> /// ///</code> ///</example> publicstringRender(Hashtablevalues) { StringBuilderresult=newStringBuilder(8*1024); inti=0; for(i=0;i<_tagCount;i++) { result.Append(_contentParts[i]); if(values[_tags[i].Name]!=null) result.Append(values[_tags[i].Name]); else result.Append("{"+_tags[i].Name+"}"); } result.Append(_contentParts[i]); returnresult.ToString(); } ///<summary> ///用指定的值生成文本 ///</summary> ///<paramname="args">各标志对应的值(忽略标志名,第一个标志对应第一个参数,以此类推)</param> ///<returns>生成的文本</returns> ///<example>以下代码用文本模板生成IMG标志 ///<code> ///staticclassProgram ///{ ///[STAThread] ///staticvoidMain() ///{ ///TextTemplatetemp=newTextTemplate("<imgsrc='{src}'alt='{alt}'/>"); ///Console.WriteLine(temp.Render("pic.bmp","Image")); ///Hashtablevalues=newHashtable(); ///values.Add("src","pic.bmp"); ///values.Add("alt","image"); ///Console.WriteLine(temp.Render(values)); ///} ///} /// ///输出为: ///<imgsrc='pic.bmp'alt='Image'/> ///<imgsrc='pic.bmp'alt='image'/> /// ///</code> ///</example> publicstringRender(paramsobject[]args) { StringBuilderresult=newStringBuilder(2*1024); inti=0; for(i=0;i<_tagCount;i++) { result.Append(_contentParts[i]); result.Append(args[i].ToString()); } result.Append(_contentParts[i]); returnresult.ToString(); } ///<summary> ///用指定的值生成文本,并保存到文件中 ///</summary> ///<paramname="file">要保存的文件路径</param> ///<paramname="encoding">文件的编码</param> ///<paramname="values">各标志对应的值(用标志名作为key)</param> publicvoidSaveAs(stringfile,Encodingencoding,Hashtablevalues) { StreamWritersw=newStreamWriter(file,false,encoding); try { Stringcontent=Render(values); sw.Write(content); } catch(Exception) { sw.Close(); throw; } sw.Close(); } ///<summary> ///用指定的值生成文本,并保存到文件中 ///</summary> ///<paramname="file">要保存的文件路径</param> ///<paramname="encoding">文件的编码</param> ///<paramname="args">各标志对应的值(忽略标志名,第一个标志对应第一个参数,以此类推)</param> publicvoidSaveAs(stringfile,Encodingencoding,paramsobject[]args) { StreamWritersw=newStreamWriter(file,false,encoding); try { Stringcontent=Render(args); sw.Write(content); } catch(Exception) { sw.Close(); throw; } sw.Close(); } ///<summary> ///将模板以指定的分隔标志分隔成小模板 ///</summary> ///<paramname="splitTag"></param> ///<returns></returns> publicTextTemplate[]Split(stringsplitTag) { List<TextTemplate>temps=newList<TextTemplate>(); List<string>contentParts=newList<string>(); List<TextTemplateTag>tags=newList<TextTemplateTag>(); inti=0; foreach(stringcontentin_contentParts) { contentParts.Add(content); if(i>=_tags.Length||_tags[i].Name==splitTag) { TextTemplatenewTemp=newTextTemplate(); newTemp._contentParts=contentParts.ToArray(); newTemp._tags=tags.ToArray(); newTemp._tagCount=tags.Count; temps.Add(newTemp); contentParts.Clear(); tags.Clear(); } else tags.Add(newTextTemplateTag(_tags[i].Name,_tags[i].Position,_tags[i].Length)); i++; } returntemps.ToArray(); } } internalclassTextTemplateTag { int_position,_length; string_name; publicTextTemplateTag(stringname,intpos,intlen) { _name=name; _position=pos; _length=len; } publicstringName { get{return_name;} } publicintPosition { get{return_position;} } publicintLength { get{return_length;} } }
实例代码:
staticclassProgram { [STAThread] staticvoidMain() { TextTemplatetemp=newTextTemplate("<imgsrc='{src}'alt='{alt}'/>"); Console.WriteLine(temp.Render("pic.bmp","Image")); Hashtablevalues=newHashtable(); values.Add("src","pic.bmp"); values.Add("alt","image"); Console.WriteLine(temp.Render(values)); } }
输出为:
<imgsrc='pic.bmp'alt='Image'/>
<imgsrc='pic.bmp'alt='image'/>
其他应用:
TextTemplate还可以用来在安装网站时生成Web.Config文件,只需定义以下模板:
<?xmlversion="1.0"?> <configurationxmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <appSettings></appSettings> <connectionStrings> <add name="DJDB.LocalSqlServer" connectionString="{CONNECTIONSTRING}" providerName="System.Data.SqlClient" /> </connectionStrings> 其他配置 </configuration>
在设置标志CONNECTIONSTRING的值即可,这种方法比用XMLDocument类要方便得多。
总结:
TextTemplate的优点有:
1、模板只在初始化时就分析并分割存储,当使用同一模板生成多个页面时,只是简单的件模板内容和标志的值连接起来,不需要每次都去分析模板,如果使用string的Replace方法则每一次都要去分析字符串,而且如果标志值中含有标志,会影响生成的页面。
2、模板可以从文件读入,因此模板文件可以使用各种网页制作工具编辑。
更多关于C#相关内容感兴趣的读者可查看本站专题:《C#数据结构与算法教程》、《C#常见控件用法教程》、《C#面向对象程序设计入门教程》及《C#程序设计之线程使用技巧总结》
希望本文所述对大家C#程序设计有所帮助。