Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Automatically Translate your .NET resource files with Google Translate

0.00/5 (No votes)
27 Oct 2006 1  
This article talks about building an application to translate .NET resource files like .resx and .js using Google Translate, for internationalization testing.

Introduction

With many more applications coming up with localized versions, it is important to test if the application is ready for that after moving the resources out of the code. We have easy ways of taking strings out of the code, using resx files, satellite DLLs, and external string files (a client side js file). A quick test would be to see if all the strings are picked up from an external file. One step further would be to make sure strings in other languages (the localized ones) are displayed properly in our application. As many point out, it is important to test with European and Asian languages that use multi-byte encoding. I started off with this testing, and thought that I will copy-paste some of the strings from the web on these languages to carry out the testing. On looking around the web, I got to know about Google Translate and I was excited, and I found a way to test my application in all languages that Google supports! As I started with it, oh, it was a pain... picking up strings one by one, translating them into the different languages .... I thought it would have been good if I had an automatic tool (there is Google for that to search and tell me!).

Google returned me with a result, a way of calling Google Translate from our application, a good article and accompanying source code by Peter A. Bromberg. I thought I got what I wanted and with two lines of code I could make it work for me, but it was not so, it made me explore so many other stuff and finally made me post here so that many others could benefit and also help me refine my first C# application.

Background

I fully agree with Peter on "don't reinvent the wheel", having been with application development for over 7 years. I have gained most part of my knowledge through the web with those who had shared their two cents. I started with his code and ran it on my machine. Oops, I didn't get the result. On getting into debug mode, I found that the web scraper he was using, WebWagon, did not support proxies. Once again, it was Google time and I added the code below to use the default proxy authentication to get his code working:

//Set Proxy settings to the  HttpWebRequest object  

hrqURL.Proxy = (WebProxy) GlobalProxySelection.Select;
hrqURL.Proxy.Credentials = CredentialCache.DefaultCredentials;

Then I started off with my project, translating my resx file, and upgrading it with version after versions. The first version used direct XML parsing of the resx file as I was not aware of ResXResourceReader. The second version included support for strings in a js file also as some string resources were part of the client side script. The next version removed the XML parsing and used ResXResourceReader and ResXResourceWriter. Then, to avoid the screen hanging, I added thread support and a progress bar to the application, and I have attached that version here. I am still thinking of working on a version supporting Altavista's Babelfish also. (I am very well aware that this code will break once the Google Translate page or the Babelfish page changes, but I hope it won't be in the near future and always there will be some one to break it through and get it working!)

Using the code

I have used Peter's WebWagon project as it is other than the few tweaks to get it working for me. The first one was the proxy support as I said earlier. Asian characters were not getting returned properly in his code and that was the main requirement for me to go for this application. I did a lot of trial and error to get this piece of code into WebWagon so that it supported UTF-8 encoding:

//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)";

Also, the encoding of the return data from the webpage was also missing. I added that to get the data encoded properly.

//Set content type for the Response Stream reader

StreamReader srdrInput = new 
  StreamReader(hrspURL.GetResponseStream(), Encoding.UTF8);

The project I have added is straightforward; for resx files, loop through the resource strings and call Translate using the ResxResourceReader, and for js, read line by line and call 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();

For getting the progress bar working, I had to do some additional coding, to get the total number of strings to be translated. For js files, I went through the file till the end once, to get all the strings. For resx, I thought using XML parsing would be much faster and used a piece of code I already had in my first version:

//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;

Points of interest

As my first application in C#, I got a chance to know more stuff about: web scraping, multithreading, XML parsing, and using different UI controls, and lot more!

Reference

History

  • V1.0 - Initial update on 26 Dec 2005.
  • 27 Oct 2006 - Fixed code to work with the new changes in the Google Translate page.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here