特殊的多语言解决方案

一直以来多语言问题都是个让人头疼的问题,不是这个问题有多难,而是很繁琐,而我们目前的这个项目有点特殊,我希望最大限度的化繁为简,以下是我解决这个问题的方案。
我们的项目有这样两个前提:
1、要支持多语言但最多三种语言,一般情况下就两种语言,所以并没有随时切换语言的要求。
2、我们希望有一种可以初期不用管语言问题,之后统一翻译的方案
基于这么两点,我们提出了这样的方案:
1、初期写程序时不用关心多语言的翻译工作,只要将所有使用到中文的地方都用{}扩上
2、在数据库中Chinese会设置为唯一约束
3、所有的翻译工作会在BasePage中的Render方法中作
4、所有的页面会继承BasePage
5、翻译时会根据当前的语言设置构建以language表中Chinese做key,相应的语言为value的字典,然后查找需要翻译的字符串是不是在字典中,如果不在就生成这一行。

 
数据库设计四个字段

ID,Chinese,English,Other

BasePage源码

 

   1using System;  
   
2using System.Data;  
   
3using System.Configuration;  
   
4using System.Linq;  
   
5using System.Web;  
   
6using System.Web.Security;  
   
7using System.Web.UI;  
   
8using System.Web.UI.HtmlControls;  
   
9using System.Web.UI.WebControls;  
  
10using System.Web.UI.WebControls.WebParts;  
  
11using System.Xml.Linq;  
  
12using System.Text.RegularExpressions;  
  
13using System.Text;  
  
14using System.Collections;  
  
15using System.Collections.Generic;  
  
16using System.IO;  
  
17using System.Diagnostics;  
  
18.   
  
19/// <summary>  
  20///BasePage 的摘要说明  
  21/// </summary>  
  22public class BasePage : System.Web.UI.Page  
  
23. {  
  
24.     //利用Dictionary来筛选所有的多语言标签,然后做替换,可以缓存  
  25.     Dictionary<stringstring> dic;  
  
26.     public BasePage()  
  
27.     {  
  
28.   
  
29.     }  
  
30.     //需要替换的标签,标签头为数字字母下划线汉字  
  31.   
  
32.     static readonly Regex re = new Regex  
  
33.         (@"((\{)|(\%7B))[\w\-\+\|u4e00-\u9fa5]+?((\})|(\%7D))",  
  
34.         RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);  
  
35.   
  
36.     //不需要替换的标签  
  37.     static readonly Regex re_nr = new  
  
38.         Regex(@"<NOREPLACE>[\w\W]*?</NOREPLACE>", RegexOptions.Multiline | RegexOptions.IgnoreCase);  
  
39.   
  
40.     private string RenderTag(ref string content)  
  
41.     {  
  
42.         if (re_nr.IsMatch(content))//不需要替换标签  
  43.         {  
  
44.             StringBuilder sb = new StringBuilder();  
  
45.   
  
46.             MatchCollection grouplist = re_nr.Matches(content);  
  
47.             string[] reList = re_nr.Split(content);  
  
48.   
  
49.             for (int i = 0; i < grouplist.Count; i++)  
  
50.             {  
  
51.                 sb.Append(ReplaceTag(ref reList[i]));  
  
52.                 sb.Append(grouplist[i].Value);  
  
53.                 sb.Append(ReplaceTag(ref reList[i + 1]));  
  
54.             }  
  
55.   
  
56.             content = sb.ToString();  
  
57.         }  
  
58.         else  
  
59.         {  
  
60.             content = ReplaceTag(ref content);  
  
61.         }  
  
62.         return content;  
  
63.     }  
  
64.   
  
65.     private string ReplaceTag(ref string content)  
  
66.     {  
  
67.         //模板标签{yes},{no},{search}  
  68.         MatchCollection mc = re.Matches(content);  
  
69.   
  
70.         if (dic == null)  
  
71.         {  
  
72.             dic = LanguageManager.GetResource();  
  
73.         }  
  
74.   
  
75.         for (int i = 0; i < mc.Count; i++)  
  
76.         {  
  
77.             //如果数据库中还没有此字符串  
  78.             if (!dic.ContainsKey(mc[i].Value.TrimStart('{').TrimEnd('}')))  
  
79.             {  
  
80.                  content = content.Replace(mc[i].Value, mc[i].Value.TrimStart('{').TrimEnd('}'));  
  
81.   
  
82.                 if (!dic.ContainsKey(mc[i].Value.TrimStart('{').TrimEnd('}')))  
  
83.                 {  
  
84.                     LanguageManager.AddLanguageString(mc[i].Value.TrimStart('{').TrimEnd('}'));  
  
85.                 }  
  
86.             }  
  
87.             else if (dic[mc[i].Value.TrimStart('{').TrimEnd('}')] == null)  
  
88.             {  
  
89.                 content = content.Replace(mc[i].Value, "$$$$");  
  
90.             }  
  
91.             else  
  
92.             {  
  
93.   
  
94.                 content = content.Replace(mc[i].Value, dic[mc[i].Value.TrimStart('{').TrimEnd('}')].ToString());  
  
95.   
  
96.   
  
97.             }  
  
98.         }  
  
99.         dic.Clear();  
 
100.         return content;  
 
101.     }  
 
102.     protected override void Render(HtmlTextWriter writer)  
 
103.     {  
 
104.   
 
105.         Stopwatch stopwatch = new Stopwatch();  
 
106.         stopwatch.Reset();  
 
107.         stopwatch.Start();  
 
108.         try  
 
109.         {  
 
110.             //会把页面的输出结果存储在这个StringBuilder中  
 111.             StringBuilder sb = new StringBuilder();  
 
112.             StringWriter sw = new StringWriter(sb);  
 
113.             HtmlTextWriter htw = new HtmlTextWriter(sw);  
 
114.             base.Render(htw);  
 
115.             string content = sb.ToString();  
 
116.   
 
117.             content = RenderTag(ref content);  
 
118.   
 
119.             //重新写入页面  
 120.             writer.Write(content);  
 
121.   
 
122.         }  
 
123.         catch (Exception ex)  
 
124.         {  
 
125.             Response.Write(ex.ToString());  
 
126.             Response.End();  
 
127.         }  
 
128.         finally  
 
129.         {  
 
130.             stopwatch.Stop();  
 
131.             Response.Write("runtime:" + stopwatch.ElapsedMilliseconds.ToString() + "ms");  
 
132.         }  
 
133.   
 
134.     }  
 
135. } 
posted @ 2009-01-21 17:50  TONYBINLJ  阅读(267)  评论(0编辑  收藏  举报