Table Format to Hold Data

S

Shapper

Hello,

I need to store some strings in different languages as follows:

"Hello", "en" ; "Olá", "pt" ; "Bounjour", "fr"

"Goodbye", "en" ; "Adeus", "pt" ; "Adieu", "fr"

Then I would have two methods:

String Translate(String value, String fromLanguage, String toLanguage);

IEnumerable<String>Translate(IEnumerable<String>, String fromLanguage, String toLanguage);

The reason why I always specify the fromLanguage is because I might have a String which is the same in two languages / cultures.

So Translate("Adieu", "fr", "en") would return "Goodbye".

1 - What data format should I use for this?

2 - What is the best way to implement the two methods in terms of performance?

NOTES:

In my example the Strings are words but can also be phrases ...

I don't want to use an External Service or Resources. I need to keep it flexible and changeable.

I am looking to use Linq with it ... So maybe using Lists, Dictionary, etc?

What do you advice me to do?

Thank You,

Miguel
 
B

bradbury9

El miércoles, 14 de noviembre de 2012 15:23:15 UTC+1, Shapper escribió:
Hello,



I need to store some strings in different languages as follows:



"Hello", "en" ; "Olá", "pt" ; "Bounjour", "fr"



"Goodbye", "en" ; "Adeus", "pt" ; "Adieu", "fr"



Then I would have two methods:



String Translate(String value, String fromLanguage, String toLanguage);



IEnumerable<String>Translate(IEnumerable<String>, String fromLanguage, String toLanguage);



The reason why I always specify the fromLanguage is because I might have a String which is the same in two languages / cultures.



So Translate("Adieu", "fr", "en") would return "Goodbye".



1 - What data format should I use for this?



2 - What is the best way to implement the two methods in terms of performance?



NOTES:



In my example the Strings are words but can also be phrases ...



I don't want to use an External Service or Resources. I need to keep it flexible and changeable.



I am looking to use Linq with it ... So maybe using Lists, Dictionary, etc?



What do you advice me to do?



Thank You,



Miguel

Globalization and localization.

ASP.NET: http://msdn.microsoft.com/en-us/library/c6zyy3s9(v=vs.100).aspx
Windows Forms: http://msdn.microsoft.com/en-us/library/y99d1cd3(v=vs.71).aspx

Hope it helps
 
S

Shapper

El miércoles, 14 de noviembre de 2012 15:23:15 UTC+1, Shapper escribió:




Globalization and localization.



ASP.NET: http://msdn.microsoft.com/en-us/library/c6zyy3s9(v=vs.100)..aspx

Windows Forms: http://msdn.microsoft.com/en-us/library/y99d1cd3(v=vs.71).aspx



Hope it helps

I do know all about that ...
But as I mentioned I don't want to use Resources.

This is a really specific situation inside an application.
So I am looking for something around what I described.

Thank You,
Miguel
 
B

bradbury9

El miércoles, 14 de noviembre de 2012 17:36:53 UTC+1, Shapper escribió:
I do know all about that ...

But as I mentioned I don't want to use Resources.



This is a really specific situation inside an application.

So I am looking for something around what I described.



Thank You,

Miguel

I would use XML files with an DTD which enforces that a certain node has all required languages.
Xml files can be searched with Linq.
<translation name='username'>
<es>Usuario</es>
<en>User</en>
<es_EU>Basque username</es_EU>
</translation>

Notes:
- Be carefull with Xml file encoding, so the file type does not restrict the languages charsets.
- Thats not and standar choice, I would use resources and globalization
 
S

Shapper

El miércoles, 14 de noviembre de 2012 17:36:53 UTC+1, Shapper escribió:




I would use XML files with an DTD which enforces that a certain node has all required languages.

Xml files can be searched with Linq.

<translation name='username'>

<es>Usuario</es>

<en>User</en>

<es_EU>Basque username</es_EU>

</translation>



Notes:

- Be carefull with Xml file encoding, so the file type does not restrict the languages charsets.

- Thats not and standar choice, I would use resources and globalization

I am also trying to avoid XML.

This is something I really prefer to include on the application.

Again, I am using this to localize very specific parts of the application which possible changes always occurs with a new compilation.

To make things easier I am trying to concentrate all those translations in one place.

I came up with the following class:

public class Pair {
public String Content { get; set; }
public String Culture { get; set; }
public Pair(String content, String culture) {
Content = content;
Culture = culture;
}
}

Then I use List<List<Pair>> to hold the data:

List<List<Pair>> data = new List<List<Pair>>();

And I get it as follows:

data.Add(new List<Pair> { new Pair("Hello", "en"), new Pair("Olá", "pt"), new Pair("Bounjour", "fr") });
data.Add(new List<Pair> { new Pair("Bye", "en"), new Pair("Adeus", "pt"),new Pair("Adieu", "fr") });

List<Pair> row = data.First(x => x.Any(y => y.Content == "Bye" && y.Culture == "en"));

String translated = row.First(x => x.Culture == "pt").Content; //RETURNS Adeus

It does what I am looking for ...

Any feedback is welcome.

Thank You,
Miguel
 
S

Shapper

Hello,



I need to store some strings in different languages as follows:



"Hello", "en" ; "Olá", "pt" ; "Bounjour", "fr"



"Goodbye", "en" ; "Adeus", "pt" ; "Adieu", "fr"



Then I would have two methods:



String Translate(String value, String fromLanguage, String toLanguage);



IEnumerable<String>Translate(IEnumerable<String>, String fromLanguage, String toLanguage);



The reason why I always specify the fromLanguage is because I might have a String which is the same in two languages / cultures.



So Translate("Adieu", "fr", "en") would return "Goodbye".



1 - What data format should I use for this?



2 - What is the best way to implement the two methods in terms of performance?



NOTES:



In my example the Strings are words but can also be phrases ...



I don't want to use an External Service or Resources. I need to keep it flexible and changeable.



I am looking to use Linq with it ... So maybe using Lists, Dictionary, etc?



What do you advice me to do?



Thank You,



Miguel

Hello,

I think I found the best option for this:
List<Dictionary<String, String>>

Thank You,
Miguel
 
B

Brian Cryer

Shapper said:
I am also trying to avoid XML.

This is something I really prefer to include on the application.

Again, I am using this to localize very specific parts of the application
which possible changes always
occurs with a new compilation.

To make things easier I am trying to concentrate all those translations in
one place.

I came up with the following class:

public class Pair {
public String Content { get; set; }
public String Culture { get; set; }
public Pair(String content, String culture) {
Content = content;
Culture = culture;
}
}

Then I use List<List<Pair>> to hold the data:

List<List<Pair>> data = new List<List<Pair>>();

And I get it as follows:

data.Add(new List<Pair> { new Pair("Hello", "en"), new Pair("Olá",
"pt"), new Pair("Bounjour", "fr") });
data.Add(new List<Pair> { new Pair("Bye", "en"), new Pair("Adeus",
"pt"), new Pair("Adieu", "fr") });

List<Pair> row = data.First(x => x.Any(y => y.Content == "Bye" &&
y.Culture == "en"));

String translated = row.First(x => x.Culture == "pt").Content; //
RETURNS Adeus

It does what I am looking for ...

Any feedback is welcome.

Honest feedback: Yuck.

1. Consider what your reasons are for not using the globalization and
localization resources provided for you. You may have good reason, but don't
reject what is there out of hand.

2. Your class is the easy bit. What is yuck is the notion of hard coding
these in your application, because you then need to go back to the code each
time you need to add a new translation or a new language. Better to have an
external resource from which you can load them. Whilst XML wouldn't be my
first choice, it does provide one means. Possibly a better approach would be
an external database.

3. If you are serious about languages then you will also need to consider
reading order - although it might not make much difference for isolated
words.

Hope this helps.
 
S

Shapper

in message


















Honest feedback: Yuck.

1. Consider what your reasons are for not using the globalization and
localization resources provided for you. You may have good reason, but don't
reject what is there out of hand.

I really did consider Resources for this case.
And I have been using it in many projects ...

But in this particular case it is to restricted.
I need something which functionality I can extend.
2. Your class is the easy bit. What is yuck is the notion of hard coding

these in your application, because you then need to go back to the code each

time you need to add a new translation or a new language. Better to have an

external resource from which you can load them. Whilst XML wouldn't be my

first choice, it does provide one means. Possibly a better approach wouldbe

an external database.

Brian, that is the point I tried to explain, maybe not well:

I am already using a SQL database which includes localization.

But there are parts of the application where I do not want to use it:

1 - Localize a Route;
2 - Localize a list originated by an enum;
3 - Localize a 404 error message ...

These parts of the application in fact will rarely change.

And when they change it will always be with a new application version.

By doing this way I can make it flexible enough to take a string, a list ofstrings or even an enum by adding an "adapter" in the pipeline.

Instead of having this localization done across the application my intention is to have it in a centralized place ...

NOTES:

- I will not have a huge list of strings / phrases to localize.
Maybe 200 at its maximum on the entire application ...
Usually defined in 4 classes (each one for a section of the application).

- Everything else will be localized on the SQL database (Content, so on).

Please, don't take me wrong. I am open to any advice.

But when I say I do not want to use Resources, SQL or XML is because I did really used these three options in the past.

And they were, for this kind of situation, or to rigid, or in case of the SQL problematic because the need of changing something in the code would always be dependent of changes in the database and also added database calls for no need.
3. If you are serious about languages then you will also need to consider

reading order - although it might not make much difference for isolated

words.

Sorry, could you explain what do you mean?

I am going to post the code I have at the moment in a different thread:
https://groups.google.com/forum/?fr...ft.public.dotnet.languages.csharp/ZZy2-2UV6GY

Thank You,
Miguel
 
B

Brian Cryer

<snip>

Sounds like you have done your homework. Sorry if I implied otherwise.
Sorry, could you explain what do you mean?

Reading-order is simply whether the text is read from left to right or right
to left. It also affects the layout of the page.

For example where I might write:

Error: 404

in Arabic the reading order is right to left so the above would be written -
and you'll have to excluse me for using English words and numbers rather
than Arabic "squiggles":

404 :Error
(and right aligned on the page)

Reading order is something you can probably ignore if you only expect to
target European/Western countries - but I'm sure someone will let me know if
I'm mistaken.

All the best.
 
A

Arne Vajhøj

I need to store some strings in different languages as follows:

"Hello", "en" ; "Olá", "pt" ; "Bounjour", "fr"

"Goodbye", "en" ; "Adeus", "pt" ; "Adieu", "fr"

Then I would have two methods:

String Translate(String value, String fromLanguage, String toLanguage);

IEnumerable<String>Translate(IEnumerable<String>, String fromLanguage, String toLanguage);

The reason why I always specify the fromLanguage is because I might have a String which is the same in two languages / cultures.

So Translate("Adieu", "fr", "en") would return "Goodbye".

1 - What data format should I use for this?

2 - What is the best way to implement the two methods in terms of performance?

NOTES:

In my example the Strings are words but can also be phrases ...

I don't want to use an External Service or Resources. I need to keep it flexible and changeable.

I am looking to use Linq with it ... So maybe using Lists, Dictionary, etc?

What do you advice me to do?

I have suggested it a couple of times already:

public class Translation
{
private Dictionary<string, Dictionary<int, string>> forward;
private Dictionary<string, Dictionary<string, int>> backward;
...
}

You could obviously also use:

public class OneTranslation
{
private Dictionary<int, string> forward;
private Dictionary<string, int> backward;
...
}
public class Translation
{
private Dictionary<string, OneTranslation> trans;
...
}

which may be a bit more elegant.

Arne
 
A

Arne Vajhøj

I have suggested it a couple of times already:

public class Translation
{
private Dictionary<string, Dictionary<int, string>> forward;
private Dictionary<string, Dictionary<string, int>> backward;
...
}

You could obviously also use:

public class OneTranslation
{
private Dictionary<int, string> forward;
private Dictionary<string, int> backward;
...
}
public class Translation
{
private Dictionary<string, OneTranslation> trans;
...
}

which may be a bit more elegant.

The trick is the forward and backward that allows any
translation between many languages as an O(1) operation.

Arne
 
A

Arne Vajhøj

El miércoles, 14 de noviembre de 2012 17:36:53 UTC+1, Shapper escribió:

I would use XML files with an DTD which enforces that a certain node has all required languages.
Xml files can be searched with Linq.
<translation name='username'>
<es>Usuario</es>
<en>User</en>
<es_EU>Basque username</es_EU>
</translation>

XML is certainly an option for persisting of data.

(I would probably prefer a database in this case, but XML is
certainly an option)

But for in memory data structure I don't see it work.

Both XmlDocument and XDocument would perform horrible for
the required operations.

Arne
 
A

Arne Vajhøj

El miércoles, 14 de noviembre de 2012 15:23:15 UTC+1, Shapper escribió:

I must admit that I find it difficult to see traditional resources
support the above API in an efficient manner.

If the requested API is not the real requirements and that the real
requirements are traditional I18N then I agree.

But that is a pretty big assumption.

:)

Arne
 
A

Arne Vajhøj

I am also trying to avoid XML.

Don't let religious belief interfere with your software design.
I came up with the following class:

public class Pair {
public String Content { get; set; }
public String Culture { get; set; }
public Pair(String content, String culture) {
Content = content;
Culture = culture;
}
}

Then I use List<List<Pair>> to hold the data:

List<List<Pair>> data = new List<List<Pair>>();

And I get it as follows:

data.Add(new List<Pair> { new Pair("Hello", "en"), new Pair("Olá", "pt"), new Pair("Bounjour", "fr") });
data.Add(new List<Pair> { new Pair("Bye", "en"), new Pair("Adeus", "pt"), new Pair("Adieu", "fr") });

List<Pair> row = data.First(x => x.Any(y => y.Content == "Bye" && y.Culture == "en"));

String translated = row.First(x => x.Culture == "pt").Content; // RETURNS Adeus

It does what I am looking for ...

Any feedback is welcome.

That is an O(n) solution for a O(1) problem.

It may be "good enough".

But it is not "good".

Arne
 
S

Shapper

Containing what?



Arne

Hello Arne,

Yes, I know you did helped me on a similar question.

At that moment I had a different approach ... Maybe wrong.

To be honest I didn't completely understand your suggestions.


Let me explain what would be the ideal in my head:

KEY = HELLO > "Hello", "en" ; "Olá", "pt" ; "Bounjour", "fr"

KEY = BYE > "Bye", "en" ; "Adeus", "pt" ; "Adieu", "fr"

Then I would have a Translator class with the following methods:

- TranslateKey(String key, String fromCulture, String toCulture);

TranslateKey("BYE", "en", "pt"); // > Adeus

- TranslateValue(String value, String fromCulture, String toCulture);

TranslateValue("Hello", "pt", "fr"); // > Adieu

NOTE: If possible also have two methods that accepts a IEnumerable<String> Keys or a IEnumerable<String> Values ... These methods would be the same asthe one before but to N values. The fromCulture and toCulture would be thesame for all.

I am looking for the following:

1 - Translator must implement ITranslator
This is because I will inject ITranslator in parts of my application;

2 - I need a configuration class such as:

public static class TranslatorConfiguration {
public static IList<TranslatorProviderBase> Providers { get; set; }
public static String DefaultFromCulture { get; set; }
public static String DefaultToCulture { get; set; }
// ...
}

A) Providers are classes that contains the translations.
I could separate some translations in 2 or 3 files.
Translator would go into these providers for search.
It would be just a table partition ...

B) DefaultFromCulture would be for example "en".
Then I would have a methods such as:
TranslateValue(String value, String toCulture);

C) DefaultToCulture would be set for example as follows:
I would set this culture maybe as follows:

SetDefaultToCulture(() => Thread.CurrentThread.CurrentCulture);

Now I could would have methods such as:
TranslateValue(String value, String toCulture)

And I can add a few more like "AllowedCultures", etc.

In App_Start I would set the configuration with all these values.
Then I would inject ITranslator and use those methods.

I hope I gave an idea on how I am trying this to "work".


I read your answers but when you suggest something like:

public class Translation
{
private Dictionary<string, Dictionary<int, string>> forward;
private Dictionary<string, Dictionary<string, int>> backward;
...
}

I am completely lost on how to integrate this in what I am trying to do.

I can post the code I have at the moment:

(NOTE: I am using List<Dictionary<String, String>> because at the moment I didn't add the Keys yet. I was trying to make it work only with Values. Butmy intention is to use Dictionary<string, Dictionary<string, int>> to Keysto.)

public interface ITranslator {
String Translate(String text, String fromCulture, String toCulture);
}

public class Translator : ITranslator {
public String Translate(String text, String fromCulture, String toCulture) {
foreach (TranslatorProviderBase provider in TranslatorConfiguration.Providers) {

Dictionary<String, String> row = provider.Table.First(x => x.Any(y => y.Key == fromCulture && y.Value == text));

if (row == null)
return null;

String translation;
if (row.TryGetValue(toCulture, out translation))
return translation;

}
return String.Empty;
}
}

public static class TranslatorConfiguration {

public static String DefaultFromCulture { get; private set; }
public static String DefaultToCulture { get; private set; }
public static IList<TranslatorProviderBase> Providers { get; private set; }

static TranslatorConfiguration() {
Cultures = new List<String>();
Providers = new List<TranslatorProviderBase>();
}

public static void AddProvider<T>() where T : TranslatorProviderBase, new() {
Providers.Add(new T());
}

public static void SetDefaultFromCulture(String culture) {
DefaultFromCulture = culture;
}

// ...

} // TranslatorConfiguration

public class TranslatorProviderBase {

public List<Dictionary<String, String>> Table { get; private set; }

public TranslatorProviderBase() {
Table = new List<Dictionary<String, String>>();
}

public void Add(Dictionary<String, String> translations) {
Table.Add(translations);
}

} // TranslatorProviderBase


A TranslatorProvider would be something as follows:

public class TranslatorProvider : TranslatorProviderBase {

public TranslatorProvider() {
Add(new Dictionary<String, String> { { "en", "Hello" }, { "pt", "Olá" }, { "fr", "Bonjour" } });
Add(new Dictionary<String, String> { { "en", "Bye" }, { "pt", "Adeus"}, { "fr", "Adieu" } });
}

} // TranslationProvider


Well this is where I am at the moment ...

Thank You,
Miguel
 
A

Arne Vajhøj

Yes, I know you did helped me on a similar question.

At that moment I had a different approach ... Maybe wrong.

To be honest I didn't completely understand your suggestions.

Let me explain what would be the ideal in my head:

KEY = HELLO > "Hello", "en" ; "Olá", "pt" ; "Bounjour", "fr"

KEY = BYE > "Bye", "en" ; "Adeus", "pt" ; "Adieu", "fr"

Then I would have a Translator class with the following methods:

- TranslateKey(String key, String fromCulture, String toCulture);

TranslateKey("BYE", "en", "pt"); // > Adeus

You mean:

TranslateKey(String key, String toCulture);

TranslateKey("BYE", "pt"); // > Adeus

??

As you are not using the from for anything.

That one is easy.

Dictionary<string,Dictionary<string,string>>

can do that.
- TranslateValue(String value, String fromCulture, String toCulture);

TranslateValue("Hello", "pt", "fr"); // > Adieu

This is more difficult.

This is where I am using the forward and backward Dictionary!!

Except that I used int as key and not string.

Let me show with string as key.

TranslateValue("Adeus", "pt", "fr"); // > Adieu

can then be done like:

string key = backward["pt"]["Adeus"]; // > BYE
forward["fr"][BYE]; // > Adieu
NOTE: If possible also have two methods that accepts a
IEnumerable<String> Keys or a IEnumerable<String> Values ... These
methods would be the same as the one before but to N values. The
fromCulture and toCulture would be the same for all.

That part is trivial.

I read your answers but when you suggest something like:

public class Translation
{
private Dictionary<string, Dictionary<int, string>> forward;
private Dictionary<string, Dictionary<string, int>> backward;
...
}

I am completely lost on how to integrate this in what I am trying to do.

See above.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top