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#程序设计有所帮助。