从标题上很难猜出我的意思,所以让我详细说明一下。
我有一个将资源(resx)用于翻译的应用程序。我有包含所有字符串的标准Strings.resx
文件,以及在特定xx-XX
区域性中重写它们的Strings.xx-XX.resx
文件。初始Strings.resx
文件具有字符串的X
数,其中特定于区域性的Strings.xx-XX.resx
文件的字符串数可能少于或等于X
数。
我正在尝试编写一个函数,它能够可靠地计算出在该语言中有多少字符串被覆盖,与初始值相比,它可以给我一个很好的整体翻译百分比。
例如,我们总共有10个字符串,es-ES
区域性中有6个字符串。当es-ES
用户启动应用程序时,他将收到一条消息,即es-ES
翻译已在60%的时间内完成。
到目前为止,我已经成功地编写了如下代码:
ushort defaultResourceSetCount = 0;
ResourceSet defaultResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.GetCultureInfo("en-US"), true, true);
if (defaultResourceSet != null) {
defaultResourceSetCount = (ushort) defaultResourceSet.Cast<object>().Count();
}
ushort currentResourceSetCount = 0;
ResourceSet currentResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, true, false);
if (currentResourceSet != null) {
currentResourceSetCount = (ushort) currentResourceSet.Cast<object>().Count();
}
if (currentResourceSetCount < defaultResourceSetCount) {
// This is our percentage that we want to calculate and show to user
float translationCompleteness = currentResourceSetCount / (float) defaultResourceSetCount;
}
上面的代码工作,但有很多方言的限制,我想解决。基本上,它只适用于在特定区域性中有特定区域性(如es-ES
和Strings
文件)的非常一般的情况--如果用户使用其他东西,比如es-UY
,他将从.NET of es-ES
中得到一个退路,但这对我们的计算不起作用。我可以将GetResourceSet()
中的GetResourceSet()
布尔值转换为true
,但是在原始Strings
文件中声明的en-US
字符串上,总是会得到形式上的回退,所以即使用户选择完全不同的文化,也总是有100%的翻译进度。
因此,基本上,以Strings.resx
中的10个资源和Strings.es-ES.resx
中的6个资源为例,应该会发生以下情况:
en-US
培养完成100%。en-GB
文化时,我们得到了100%的完成,因为它回到了en-US
,并且我们已经讨论了这个问题。es-ES
培养完成率达60%。es-UY
区域性时,我们获得了60%的完成,因为.NET认为es
,然后es-ES
作为后盾。注意,我们没有es
,但是es-ES
声明了。zh-CN
时得到0%的完成,即使我们已经讨论过的en-US
是最严重的退步。我想以最好的方式解决这个问题,我不太确定什么是,是最好的方式--我认为简单地获取资源是有效的,但对方言是有效的,但是尝试所有的父母也不起作用,因为它总是会导致en-US
。另一方面,我想假设任何比Strings.resx
更好的退路都可以被认为是翻译的,因为es-ES
对es-UY
用户是完全好的,但是en-US
对zh-CN
是不好的。另一方面,en-US
完全适合en-GB
用户。
也许我可以在某种程度上比较两个ResourceSet
和tryParents
集,并比较哪些字符串是不同的?但是,这需要引用比较,因为某些字符串完全有可能在两种不同的语言中具有相同的翻译。有可能吗?
欢迎任何建议。
发布于 2017-03-11 08:13:21
这是我就这个问题想出的最好的办法:
if (CultureInfo.CurrentCulture.TwoLetterISOLanguageName.Equals("en")) {
return;
}
ResourceSet defaultResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.GetCultureInfo("en-US"), true, true);
if (defaultResourceSet == null) {
return;
}
HashSet<DictionaryEntry> defaultStringObjects = new HashSet<DictionaryEntry>(defaultResourceSet.Cast<DictionaryEntry>());
if (defaultStringObjects.Count == 0) {
return;
}
ResourceSet currentResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, true, true);
if (currentResourceSet == null) {
return;
}
HashSet<DictionaryEntry> currentStringObjects = new HashSet<DictionaryEntry>(currentResourceSet.Cast<DictionaryEntry>());
if (currentStringObjects.Count >= defaultStringObjects.Count) {
// Either we have 100% finished translation, or we're missing it entirely and using en-US
HashSet<DictionaryEntry> testStringObjects = new HashSet<DictionaryEntry>(currentStringObjects);
testStringObjects.ExceptWith(defaultStringObjects);
// If we got 0 as final result, this is the missing language
// Otherwise it's just a small amount of strings that happen to be the same
if (testStringObjects.Count == 0) {
currentStringObjects = testStringObjects;
}
}
if (currentStringObjects.Count < defaultStringObjects.Count) {
float translationCompleteness = currentStringObjects.Count / (float) defaultStringObjects.Count;
Console.WriteLine("Do something with translation completeness: " + translationCompleteness);
}
它只需要两个相当不错的假设:
我对这个解决方案很满意。
https://stackoverflow.com/questions/42598732
复制相似问题