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"
代码:
using system; using system.collections.generic; using system.text; using system.text.regularexpressions; using system.collections; using system.io; /// <summary> /// 表示一个文本模板,该类使用一个字符串作为模板,通过将模板中的标志替换为对应的值(模板中的标志用 {标志名} 表示)生成新的文本 /// </summary> /// <example>以下代码用文本模板生成img标志 /// <code> /// static class program /// { /// [stathread] /// static void main() /// { /// texttemplate temp = new texttemplate("<img src='{src}' alt='{alt}' />"); /// console.writeline(temp.render("pic.bmp","image")); /// hashtable values = new hashtable(); /// values.add("src", "pic.bmp"); /// values.add("alt", "image"); /// console.writeline(temp.render(values)); /// } /// } /// /// 输出为: /// <img src='pic.bmp' alt='image' /> /// <img src='pic.bmp' alt='image' /> /// /// </code> /// </example> public class texttemplate { texttemplatetag[] _tags; string[] _contentparts; int _tagcount; private texttemplate() { _tagcount = 0; _tags = null; _contentparts = null; } /// <summary> /// 用指定的模板初始化texttemplate /// </summary> /// <param name="content">模板内容</param> public texttemplate(string content) { fromstring(content); } /// <summary> /// 用指定的模板初始化texttemplate,模板内容重文件读入 /// </summary> /// <param name="file">模板文件位置</param> /// <param name="encoding">文件使用的编码</param> public texttemplate(string file, encoding encoding) { streamreader sr = new streamreader(file, encoding); try { string content = sr.readtoend(); fromstring(content); } catch (exception) { sr.close(); throw; } sr.close(); } /// <summary> /// 读入模板并以标志为分割点分割模板 /// </summary> /// <param name="content"></param> private void fromstring(string content) { matchcollection mc = regex.matches(content, "{\\w+}"); _tagcount = mc.count; _tags = new texttemplatetag[mc.count]; _contentparts = new string[mc.count + 1]; int index = 0; foreach (match m in mc) { _tags[index++] = new texttemplatetag(m.value.substring(1, m.value.length - 2), m.index, m.length); } int start = 0; index = 0; foreach (texttemplatetag con in _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> /// <param name="values">各标志对应的值(用标志名作为key)</param> /// <returns>生成的文本</returns> /// <example>以下代码用文本模板生成img标志 /// <code> /// static class program /// { /// [stathread] /// static void main() /// { /// texttemplate temp = new texttemplate("<img src='{src}' alt='{alt}' />"); /// console.writeline(temp.render("pic.bmp","image")); /// hashtable values = new hashtable(); /// values.add("src", "pic.bmp"); /// values.add("alt", "image"); /// console.writeline(temp.render(values)); /// } /// } /// /// 输出为: /// <img src='pic.bmp' alt='image' /> /// <img src='pic.bmp' alt='image' /> /// /// </code> /// </example> public string render(hashtable values) { stringbuilder result = new stringbuilder(8 * 1024); int i = 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]); return result.tostring(); } /// <summary> /// 用指定的值生成文本 /// </summary> /// <param name="args">各标志对应的值(忽略标志名,第一个标志对应第一个参数,以此类推)</param> /// <returns>生成的文本</returns> /// <example>以下代码用文本模板生成img标志 /// <code> /// static class program /// { /// [stathread] /// static void main() /// { /// texttemplate temp = new texttemplate("<img src='{src}' alt='{alt}' />"); /// console.writeline(temp.render("pic.bmp","image")); /// hashtable values = new hashtable(); /// values.add("src", "pic.bmp"); /// values.add("alt", "image"); /// console.writeline(temp.render(values)); /// } /// } /// /// 输出为: /// <img src='pic.bmp' alt='image' /> /// <img src='pic.bmp' alt='image' /> /// /// </code> /// </example> public string render(params object[] args) { stringbuilder result = new stringbuilder(2 * 1024); int i = 0; for (i = 0; i < _tagcount; i++) { result.append(_contentparts[i]); result.append(args[i].tostring()); } result.append(_contentparts[i]); return result.tostring(); } /// <summary> /// 用指定的值生成文本,并保存到文件中 /// </summary> /// <param name="file">要保存的文件路径</param> /// <param name="encoding">文件的编码</param> /// <param name="values">各标志对应的值(用标志名作为key)</param> public void saveas(string file, encoding encoding, hashtable values) { streamwriter sw = new streamwriter(file, false, encoding); try { string content = render(values); sw.write(content); } catch (exception) { sw.close(); throw; } sw.close(); } /// <summary> /// 用指定的值生成文本,并保存到文件中 /// </summary> /// <param name="file">要保存的文件路径</param> /// <param name="encoding">文件的编码</param> /// <param name="args">各标志对应的值(忽略标志名,第一个标志对应第一个参数,以此类推)</param> public void saveas(string file, encoding encoding, params object[] args) { streamwriter sw = new streamwriter(file, false, encoding); try { string content = render(args); sw.write(content); } catch (exception) { sw.close(); throw; } sw.close(); } /// <summary> /// 将模板以指定的分隔标志分隔成小模板 /// </summary> /// <param name="splittag"></param> /// <returns></returns> public texttemplate[] split(string splittag) { list<texttemplate> temps = new list<texttemplate>(); list<string> contentparts = new list<string>(); list<texttemplatetag> tags = new list<texttemplatetag>(); int i = 0; foreach (string content in _contentparts) { contentparts.add(content); if (i >= _tags.length || _tags[i].name == splittag) { texttemplate newtemp = new texttemplate(); newtemp._contentparts = contentparts.toarray(); newtemp._tags = tags.toarray(); newtemp._tagcount = tags.count; temps.add(newtemp); contentparts.clear(); tags.clear(); } else tags.add(new texttemplatetag(_tags[i].name, _tags[i].position, _tags[i].length)); i++; } return temps.toarray(); } } internal class texttemplatetag { int _position, _length; string _name; public texttemplatetag(string name, int pos, int len) { _name = name; _position = pos; _length = len; } public string name { get { return _name; } } public int position { get { return _position; } } public int length { get { return _length; } } }
实例代码:
static class program { [stathread] static void main() { texttemplate temp = new texttemplate("<img src='{src}' alt='{alt}' />"); console.writeline(temp.render("pic.bmp","image")); hashtable values = new hashtable(); values.add("src", "pic.bmp"); values.add("alt", "image"); console.writeline(temp.render(values)); } }
输出为:
<img src='pic.bmp' alt='image' />
<img src='pic.bmp' alt='image' />
其他应用:
texttemplate还可以用来在安装网站时生成web.config文件,只需定义以下模板:
<?xml version="1.0"?> <configuration xmlns="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#程序设计有所帮助。