|
using System;
using System.IO;
using System.Xml;
using System.Net;
using System.Text;
namespace org.vonburg.UtilityApps.App_Localizer
{
/// <summary>
/// Provides mechanisms to read and translate resource files using Google Translate
/// </summary>
public class Localizer
{
#region Constants
/// <summary>
/// The URL to access Google Translater at.
/// You should append sourcelang/destlanguage/phrase
/// e.g. "http://www.google.com/translate_t?langpair=en|es&text=Hello, world!"
/// </summary>
private const string c_GoogleTranslateUrl = "http://www.google.com/translate_t?langpair=";
#endregion
#region Constructor
/// <summary>
/// Creates a new instance of the Localizer object
/// </summary>
public Localizer()
{
}
#endregion
#region Private Methods
/// <summary>
/// Iterates through the .resx file and tranlates all entries for text properties
/// </summary>
/// <param name="resourceFilePath"></param>
/// <param name="sourceLanguageCode"></param>
/// <param name="outputLanguageCode"></param>
/// <param name="TextPropertiesOnly">True if only text properties (items where the name ends with .text) should be translated</param>
private void translateRESX(string resourceFilePath, string sourceLanguageCode, string outputLanguageCode, bool TextPropertiesOnly)
{
//variables
XmlDocument doc = null;
try
{
//open the document
doc = new XmlDocument();
doc.Load(resourceFilePath);
}
catch (Exception err)
{
throw new Exception("Failed to load the resource file.\r\n" + err.Message);
}
//get all of the data elements
XmlNodeList nodes = doc.SelectNodes("/root/data");
//loop through each node and translate the text value
for (int i = 0; nodes.Count > i; i++)
{
XmlNode node = nodes[i];
//filter out anything that has a type (as it is not a string)
XmlAttribute typeAtt = node.Attributes["type"];
if (typeAtt == null)
{
//If the TextPropertiesOnly is true, filter out any nodes where the name doesn't contain .Text
XmlAttribute nameAtt = node.Attributes["name"];
if (TextPropertiesOnly)
{
//get only the nodes where the name ends with .text
if (nameAtt != null && nameAtt.InnerText.EndsWith(".Text"))
{
//get the value node
XmlNode valueNode = node.SelectSingleNode("value");
if (valueNode != null)
{
string text = valueNode.InnerText;
if (text != null && text != "")
{
string newText = this.translatePhrase(text, sourceLanguageCode, outputLanguageCode);
valueNode.InnerText = newText;
}
}
}
}
else //get all nodes
{
//get the value node
XmlNode valueNode = node.SelectSingleNode("value");
if (valueNode != null)
{
string text = valueNode.InnerText;
if (text != null && text != "")
{
string newText = this.translatePhrase(text, sourceLanguageCode, outputLanguageCode);
valueNode.InnerText = newText;
}
}
}
}
}
//save the file
doc.Save(resourceFilePath);
}
/// <summary>
/// Iterates through the supplied .propeties file and translates all entries
/// </summary>
/// <param name="resourceFilePath"></param>
/// <param name="sourceLanguageCode"></param>
/// <param name="outputLanguageCode"></param>
private void translateProperties(string resourceFilePath, string sourceLanguageCode, string outputLanguageCode)
{
try
{
//Read the file line by line
StringBuilder sb = new StringBuilder();
using (StreamReader reader = new StreamReader(resourceFilePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
//if the line has an = in it, get the name and values
if (line.Contains("="))
{
string[] sLine = line.Split('=');
string name = sLine[0];
string value = sLine[1];
if (value != null && !value.Equals(""))
{
//translate the phrase
value = this.translatePhrase(value.Trim(), sourceLanguageCode, outputLanguageCode);
//write the new value
sb.AppendLine(name + "=" + value);
}
else
{
//write blank lines
sb.AppendLine(line);
}
}
else
{
//write non setting lines
sb.AppendLine(line);
}
}
//close the file
reader.Close();
reader.Dispose();
}
//write the new updated file
using (StreamWriter writer = new StreamWriter(resourceFilePath, false))
{
//write the entire file
writer.Write(sb.ToString());
//flush and close the file
writer.Flush();
writer.Close();
writer.Dispose();
}
}
catch (Exception err)
{
throw new Exception("An error occured reading or writing to the properties file.\r\n" + err.Message);
}
}
/// <summary>
/// Calls out to Google translate to translate the supplied phrase
/// </summary>
/// <param name="phrase"></param>
/// <param name="sourceLangCode"></param>
/// <param name="destLangCode"></param>
/// <returns></returns>
private string translatePhrase(string phrase, string sourceLangCode, string destLangCode)
{
string translatedText = null;
try
{
//create the web client
WebClient client = new WebClient();
//Open the page and get the results
string url = c_GoogleTranslateUrl + sourceLangCode + "|" + destLangCode + "&text=" + phrase;
string sPage = client.DownloadString(url);
// Parse as the page as a string
// Page can have bad HTML causing problems if you try to parse as xml
// Find the span with the title of the original string
int tagStart = sPage.IndexOf("<span title=\"" + phrase + "\"");
int tagEnd = sPage.IndexOf("</span>", tagStart);
string resultsTag = sPage.Substring(tagStart, (tagEnd - tagStart));
//get rid of the start tag
resultsTag = resultsTag.Substring(resultsTag.IndexOf(">") + 1);
//You now have the translated text
translatedText = resultsTag.Trim();
//dispose of the web client
client.Dispose();
}
catch(Exception err)
{
throw new Exception("Failed to download results from Google Translator.\r\n" + err.Message);
}
return translatedText;
}
#endregion
#region Public Methods
/// <summary>
/// Creates a copy of the resource file, and then translates it phrase by phrase.
/// </summary>
/// <param name="sourceResourceFilePath"></param>
/// <param name="outputResourceFilePath"></param>
/// <param name="sourceLanguageCode"></param>
/// <param name="outputLanguageCode"></param>
/// <param name="TextPropertiesOnly">True if only text properties (items where the name ends with .text) should be translated</param>
public void translateFile(string sourceResourceFilePath, string outputResourceFilePath, string sourceLanguageCode, string outputLanguageCode, bool TextPropertiesOnly)
{
try
{
//create the new output file
File.Copy(sourceResourceFilePath, outputResourceFilePath, true);
}
catch (Exception err)
{
throw new Exception("Failed to create output file.\r\n" + err.Message);
}
//determine the file type
string extension = Path.GetExtension(sourceResourceFilePath);
if (extension.ToLower().Equals(".resx"))
{
this.translateRESX(outputResourceFilePath, sourceLanguageCode, outputLanguageCode, TextPropertiesOnly);
//exit
return;
}
if (extension.ToLower().Equals(".properties"))
{
this.translateProperties(outputResourceFilePath, sourceLanguageCode, outputLanguageCode);
//exit
return;
}
//if we made it this far, throw an expcetion as this is not a file extension we recognize
throw new Exception("Unable to translate the supplied source resource file. Make sure your source file has either a .resx or .properties extension");
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.