从标题中猜出我的意思可能有点难,所以让我详细说明。
我有一个使用资源(resx)进行翻译的应用程序。我有标准Strings.resx
文件包含所有字符串,Strings.xx-XX.resx
文件覆盖特定xx-XX
文化中的文件。初始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
,他&#39 ;我将从es-ES
的.NET获得回退,但这对我们的计算不起作用。我可以将tryParents
中的GetResourceSet()
布尔值切换为true
,但是我始终会在原始en-US
中声明的Strings
字符串中获得回退文件,所以我们总是有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
设置进行比较并比较哪些字符串不同?但是,它需要进行参考比较,因为一些字符串可能在两种不同的语言中具有相同的翻译。它甚至可能吗?
欢迎任何建议。
答案 0 :(得分:1)
这是我提出的关于这个问题的最好的:
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);
}
它只需要两个相当不错的假设:
我对此解决方案非常满意。