Click here to Skip to main content
Click here to Skip to main content

.NET XML Based Localization

, 30 Jul 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
An article on .NET localization

Introduction & Background

During the development of my pet project, I had to solve the problem of localization. C# offers an almost perfect solution for it. If your form(s) Localization property is set to true and you give the default language, studio (or C# express) will generate a series of localizable text properties of your components, which are deployed in the project. You can edit the values in a table by you double-clicking on the *.resx file. Furthermore the editor generates a Resourcename.Designer.cs file, which contains the localized properties as static members of a class, called as the “resourcename”.

This allows for referring to any of the text values via a unique static property, to find the appropriate string values of your variables, based on the CultureInfo properties (for details please refer to the msdn). If you would like to give an additional language to your project, you have to create a new .resx file with the same name, but the name must contain the culture id. For example: LocalisationSample.resx (default resx file), LocalisationSample.en-EN.resx (English version).

Now if your project is recompiled, and the OS language settings are changed from your default language (Hungarian in my case) to English, all the translated text will be displayed in English.

Although this is a robust solution for the localization problem, I have some extra demands:

  • I wouldn’t like to recompile the project to add new languages.
  • I wouldn’t like the code size and compilation time increased by new languages.
  • I want to provide facility to the user to translate displayed texts to any language.

Result

To satisfy the above requirements, the data must be stored in a user editable XML file (.resxml). The file name of these files are created according to the following rule:

filename + _lang + .resxml, e.g.
MyResources.resxml -> English
MyResources_hu.resxml -> Hungarian

The structure of the resxml file is really simple; the following example (Fruits.resxml) contains (ids, values, description) triplets for some fruits:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <it id="APPLE_ID" value="apple" description="my favorite fruit" />
  <it id="PEAR_ID" value="pear" description="a sweet fruit" />

</root>

A static class RManager is defined, which is able to load the appropriate resxml files based on the language setting at the very beginning of the execution of your application. This class must be included in your project. To use the string variables (static properties) as global variables, an additional static class called “filename” in a filename.cs (Fruits.cs in the sample) file should be defined.

/*RMTool 1.0 generated file, do not edit!*/
using RMTool;
using System.ComponentModel;

namespace FruitsNm{
    public static class Fruits
    {
        ///<span class="code-SummaryComment"><summary></span>
        // my favorite fruit
        ///<span class="code-SummaryComment"></summary></span>
        public static string APPLE_ID { get { return RManager.GetValue("Fruits",
            "APPLE_ID"); } }

        ///<span class="code-SummaryComment"><summary></span>
        // a sweet fruit
        ///<span class="code-SummaryComment"></summary></span>

        public static string PEAR_ID { get { return RManager.GetValue("Fruits",
            "PEAR_ID"); } }

    }
} /* end of file */

To simplify the generation of resxml file and static class, I developed a free tool, called RMTool. This tool displays the data triplets (id (Name), value (Text), description) in a table of the selected resxml file.

rmtool.JPG

The Interface helps to manage, generate and translate your resource files.

Using the Code

I created a new project, and I put a Label in the Form1.

After the RManager.cs, Fruit.cs files were added to the project, and the RMTool and FruitsNm namespace were referred in the Form1 file, I was able to assign APPLE_ID language dependent string value to the Text property of label1.

The source code, the constructor of Form1:

public Form1()
{
    InitializeComponent();

    // the path of the application exe,
    // the Fruits.resxml resource file
    // is stored in this directory
    string AppPath = 
        Path.GetDirectoryName(Application.ExecutablePath);
    // get Fruits.resxml           
    RManager.GetFiles(AppPath, "");
    label1.Text = Fruits.APPLE_ID
}

and the result:

result.JPG

Summary

I presented an alternative way to the solution of the localization problem. In this way your project size and the compilation time won’t increase with new language resources, since they are stored in different XML files (resxml), which are dynamically loaded during the execution of the application. I also provided a tool to facilitate the development of resource files.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

szgerg
Software Developer (Senior)
Hungary Hungary
No Biography provided

Comments and Discussions

 
GeneralMy vote of 3 PinmemberPedroMinatel3-Mar-11 0:39 
GeneralBug PinmemberTwilightSora10-Nov-09 6:46 
GeneralBest Localization Plug-in for Visual Studio. PinmemberAlexander Nesterenko17-Dec-08 22:46 
GeneralInteresting Pinmembermerlin98131-Jul-08 4:53 
GeneralRe: Interesting Pinmemberszgerg4-Sep-08 7:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141220.1 | Last Updated 30 Jul 2008
Article Copyright 2008 by szgerg
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid