使用Google Translate自动翻译您的.NET资源文件






4.90/5 (13投票s)
2005年12月27日
4分钟阅读

164437

3822
本文介绍了如何使用Google Translate构建应用程序来翻译.NET资源文件(如.resx和.js),以进行国际化测试。
引言
随着越来越多的应用程序推出本地化版本,在将资源移出代码后,测试应用程序是否已准备好进行本地化至关重要。我们有简单的方法可以将字符串从代码中提取出来,使用resx文件、satellite DLL和外部字符串文件(客户端的js文件)。一个快速的测试方法是查看是否所有字符串都已从外部文件中正确读取。更进一步的测试是确保其他语言(本地化语言)的字符串在我们的应用程序中正确显示。正如许多人指出的那样,重要的是要使用使用多字节编码的欧洲和亚洲语言进行测试。我开始进行这项测试,并认为我会从网上复制一些这些语言的字符串来进行测试。在网上搜索时,我了解了Google Translate,我感到很兴奋,并且找到了一个用Google支持的所有语言来测试我的应用程序的方法!当我开始做的时候,哦,这太痛苦了……一个接一个地 picking up 字符串,将它们翻译成不同的语言……我想如果我有一个自动化的工具就好了(Google可以搜索并告诉我!)。
Google给了我一个结果,一种从我们的应用程序调用Google Translate的方法,一篇由Peter A. Bromberg撰写的精彩文章和附带的源代码。我认为我得到了我想要的,并且只需两行代码就可以让它为我工作,但事实并非如此,它让我探索了许多其他东西,最终让我在这里发布,以便许多其他人可以受益,也可以帮助我改进我的第一个C#应用程序。
背景
我完全同意Peter的“不要重复造轮子”的观点,我已经从事应用程序开发超过7年了。我的大部分知识都来自互联网上那些分享他们见解的人。我从他的代码开始,并在我的机器上运行了它。糟糕,我没有得到结果。在进入调试模式后,我发现他使用的网络爬虫WebWagon不支持代理。再次,是时候使用Google了,我添加了下面的代码来使用默认代理身份验证来让他的代码正常工作。
//Set Proxy settings to the HttpWebRequest object
hrqURL.Proxy = (WebProxy) GlobalProxySelection.Select;
hrqURL.Proxy.Credentials = CredentialCache.DefaultCredentials;
然后我开始了我的项目,翻译我的resx文件,并将其升级到不同的版本。第一个版本使用了直接的XML解析resx文件,因为我不知道ResXResourceReader
。第二个版本还支持js文件中的字符串,因为一些字符串资源是客户端脚本的一部分。下一个版本取消了XML解析,使用了ResXResourceReader
和ResXResourceWriter
。然后,为了避免屏幕挂起,我为应用程序添加了线程支持和进度条,并且我在这里附上了那个版本。我还在考虑开发一个支持Altavista的Babelfish的版本。(我非常清楚,一旦Google Translate页面或Babelfish页面发生变化,此代码将会失效,但我希望它不会在不久的将来发生,并且总会有人通过它并使其工作!)
使用代码
我使用了Peter的WebWagon项目,除了少数几次调整让它为我工作。第一次调整如我之前所说,是代理支持。他的代码无法正确返回亚洲字符,而这正是我选择这个应用程序的主要原因。我进行了大量的试错,才将这段代码添加到WebWagon中,使其支持UTF-8编码。
//Set content type for the HTTPWebRequest object
hrqURL.Method = "GET";
hrqURL.ContentType = "application/x-www-form-urlencoded";
hrqURL.UserAgent = "Mozilla/4.0 (compatible;" +
" MSIE 6.0; Windows NT 5.1)";
此外,网页返回数据的编码也丢失了。我添加了它,以使数据能够正确编码。
//Set content type for the Response Stream reader
StreamReader srdrInput = new
StreamReader(hrspURL.GetResponseStream(), Encoding.UTF8);
我添加的项目很简单;对于resx文件,通过ResxResourceReader
循环遍历资源字符串并调用Translate;对于js文件,逐行读取并调用Translate。
// Create a ResXResourceReader for the file items.resx.
ResXResourceReader rsxr = new ResXResourceReader(fileName);
ResXResourceWriter rsxTranslated = new ResXResourceWriter(outputFileName);
// Create an IDictionaryEnumerator to iterate through the resources.
IDictionaryEnumerator id = rsxr.GetEnumerator();
long count=0;
object[] pct;
pct = new object[1];
// Iterate through the resources
foreach (DictionaryEntry d in rsxr)
{
count++;
int percentTranslated = (int)(count*100/totalStrings);
pct[0]=percentTranslated;
this.Invoke(showProgress,pct);
string strval = d.Value.ToString();
string translatedtxt = TranslateString(strval);
//Add translated string to the output resource files
rsxTranslated.AddResource(d.Key.ToString(),translatedtxt );
}
//store back the resx file under the chosen language option
rsxTranslated.Generate();
rsxr.Close();
rsxTranslated.Close();
为了让进度条工作,我不得不进行一些额外的编码,以获取要翻译的字符串总数。对于js文件,我通读了文件直到最后,以获取所有字符串。对于resx文件,我认为使用XML解析会快得多,并使用了我的第一个版本中的一段代码。
//To get the total no of resource strings to be translated (for
//progress bar) fastest way is to read resx as xml!
XmlDocument rootNode = new XmlDocument();
rootNode.Load(fileName);
XmlNodeList dataNodes = rootNode.SelectNodes("//root/data");
int totalStrings = dataNodes.Count;
关注点
作为我的第一个C#应用程序,我获得了学习更多知识的机会:网络爬虫、多线程、XML解析、使用不同的UI控件,还有更多!
参考
历史
- V1.0 - 首次更新于2005年12月26日。
- 2006年10月27日 - 修复代码,以适应Google Translate页面上的新更改。