C#实现动态生成静态页面的类详解
本篇章节讲解C#实现动态生成静态页面的类。分享给大家供大家参考,具体如下: 动态生成静态页面有许多好处,比如生成html网页有利于被搜索引擎收录。同时,由于减少了数据访问,减轻对数据库访问的压力,提高了网页打开速度。 基本思路: 使用一个字符串作为页面模板,再页面中包含用若干标志(用 {标志名} 表示),生成页面时,将标志替换为对应的值。 实现方法: 在初始化TextTemplate实例时读入模板,以标志为分割点将模板分割成几部分,生成页面时只需简单的将模板内容和标志的值连接起来。例如: 代码: 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"); /// 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,params object[] args) { StreamWriter sw = new StreamWriter(file,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' /> 其他应用: 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#程序设计有所帮助。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |