C#實(shí)現(xiàn)動(dòng)態(tài)生成靜態(tài)頁面的類詳解
本文實(shí)例講述了C#實(shí)現(xiàn)動(dòng)態(tài)生成靜態(tài)頁面的類。分享給大家供大家參考,具體如下:
動(dòng)態(tài)生成靜態(tài)頁面有許多好處,比如生成html網(wǎng)頁有利于被搜索引擎收錄。同時(shí),由于減少了數(shù)據(jù)訪問,減輕對(duì)數(shù)據(jù)庫訪問的壓力,提高了網(wǎng)頁打開速度。
基本思路:
使用一個(gè)字符串作為頁面模板,再頁面中包含用若干標(biāo)志(用 {標(biāo)志名} 表示),生成頁面時(shí),將標(biāo)志替換為對(duì)應(yīng)的值。
實(shí)現(xiàn)方法:
在初始化TextTemplate實(shí)例時(shí)讀入模板,以標(biāo)志為分割點(diǎn)將模板分割成幾部分,生成頁面時(shí)只需簡單的將模板內(nèi)容和標(biāo)志的值連接起來。例如:
假如有一個(gè)模板 ABCD{TAG1}EFG{TAG2}HIJ{TAG3}KMUN
初始化時(shí)將模板分割成 "ABCD","EFG","HIJ","KMUN"四個(gè)字符串,
假設(shè)TAG1=“123”,TAG2=“456”,TAG3=“789”
則生成是相當(dāng)于執(zhí)行"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>
/// 表示一個(gè)文本模板,該類使用一個(gè)字符串作為模板,通過將模板中的標(biāo)志替換為對(duì)應(yīng)的值(模板中的標(biāo)志用 {標(biāo)志名} 表示)生成新的文本
/// </summary>
/// <example>以下代碼用文本模板生成IMG標(biāo)志
/// <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">模板內(nèi)容</param>
public TextTemplate(String content)
{
FromString(content);
}
/// <summary>
/// 用指定的模板初始化TextTemplate,模板內(nèi)容重文件讀入
/// </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>
/// 讀入模板并以標(biāo)志為分割點(diǎn)分割模板
/// </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">各標(biāo)志對(duì)應(yīng)的值(用標(biāo)志名作為key)</param>
/// <returns>生成的文本</returns>
/// <example>以下代碼用文本模板生成IMG標(biāo)志
/// <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">各標(biāo)志對(duì)應(yīng)的值(忽略標(biāo)志名,第一個(gè)標(biāo)志對(duì)應(yīng)第一個(gè)參數(shù),以此類推)</param>
/// <returns>生成的文本</returns>
/// <example>以下代碼用文本模板生成IMG標(biāo)志
/// <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">各標(biāo)志對(duì)應(yīng)的值(用標(biāo)志名作為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">各標(biāo)志對(duì)應(yīng)的值(忽略標(biāo)志名,第一個(gè)標(biāo)志對(duì)應(yīng)第一個(gè)參數(shù),以此類推)</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>
/// 將模板以指定的分隔標(biāo)志分隔成小模板
/// </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; }
}
}
實(shí)例代碼:
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' />
其他應(yīng)用:
TextTemplate還可以用來在安裝網(wǎng)站時(shí)生成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>
在設(shè)置標(biāo)志 CONNECTIONSTRING 的值即可,這種方法比用XMLDocument類要方便得多。
總結(jié):
TextTemplate的優(yōu)點(diǎn)有:
1、模板只在初始化時(shí)就分析并分割存儲(chǔ),當(dāng)使用同一模板生成多個(gè)頁面時(shí),只是簡單的件模板內(nèi)容和標(biāo)志的值連接起來,不需要每次都去分析模板,如果使用string的Replace方法則每一次都要去分析字符串,而且如果標(biāo)志值中含有標(biāo)志,會(huì)影響生成的頁面。
2、模板可以從文件讀入,因此模板文件可以使用各種網(wǎng)頁制作工具編輯。
更多關(guān)于C#相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《C#數(shù)據(jù)結(jié)構(gòu)與算法教程》、《C#常見控件用法教程》、《C#面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》及《C#程序設(shè)計(jì)之線程使用技巧總結(jié)》
希望本文所述對(duì)大家C#程序設(shè)計(jì)有所幫助。
相關(guān)文章
unity 如何判斷鼠標(biāo)是否在哪個(gè)UI上(兩種方法)
這篇文章主要介紹了unity 判斷鼠標(biāo)是否在哪個(gè)UI上的兩種實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04
C#中實(shí)現(xiàn)查找字符串中指定字符位置方法小結(jié)
這篇文章主要為大家介紹了C#中實(shí)現(xiàn)查找字符串中指定字符位置的常用方法,本文將以"."字符為例,詳細(xì)講解這些方法的具體使用,需要的可以參考下2024-02-02
Unity 實(shí)現(xiàn)框選游戲戰(zhàn)斗單位的思路詳解
這篇文章主要介紹了Unity 如何實(shí)現(xiàn)框選游戲戰(zhàn)斗單位,本文簡單介紹如何實(shí)現(xiàn)即時(shí)戰(zhàn)略游戲中框選戰(zhàn)斗單位的功能,需要的朋友可以參考下2022-12-12

