【问题标题】:Three layers of culture specific resource files三层文化特定资源文件
【发布时间】:2013-08-07 13:56:26
【问题描述】:

我需要一种方法来使用文化特定资源文件的第三“层”。这可能以应有的方式完成,并且可能以某种方式被黑客入侵。只要黑客不是太大,没关系!另一种解决方案也是可能的(如果我处理问题的方法有误,请告知更好的解决方案)。

通常你有一个默认资源文件,它可以作为后备。最重要的是,您可以拥有一种语言的文化特定资源。现在我想要的是一个“主题”特定的资源。

问题是我们有几个站点都有不同的主题(马、汽车、rc-units 等),当我们使用本地化资源文件中的字符串时,如果资源没有翻译成特定语言然而,它会回退到默认语言英语。酷!

一个问题示例:我们有短语“Add your horse”和“Add your car”,在英语中可能看起来相同(在语法方面),但在波兰语或罗马尼亚语中不一定如此!

所以我想,如果可能的话,我们应该有一个带有“添加您的 {0}”的英文文件,然后是一个带有波兰语等效句子的波兰语文件,除此之外还有一个“汽车”特定的波兰语翻译语法适合单词“Car”的地方,以及语法适合单词“Horse”的“Horse”波兰语翻译。

使用两种或三种语言的两个或三个主题可能不会那么糟糕。很容易认为我们可以在处理这少数情况的代码中进行切换。问题是,我们有 15 个主题,使用 6 种不同的语言,并且还在不断扩展。

希望有一些巧妙的技巧或一些很少使用的奇异功能的知识!

提前致谢

【问题讨论】:

  • 这听起来太复杂了,很容易变得难以管理。为什么不坚持标准方法,将“添加您的汽车”和“添加您的马”作为两个完全独立的字符串?
  • 那么我还需要: * 添加你的遥控单元 * 添加你的拖拉机 * 添加你的猫 * 添加你的狗 * 添加你的护卫舰 德语三串,丹麦语十串,法语三串,最后一个用于罗马尼亚语、西班牙语、波兰语和奥地利语。我们还计划进一步扩展(目前有四个新站点排队)
  • 假设您愿意解决具体单词带来的性别/变格/等差异(正如 ThoBa 在他的回答中提到的),您的具体示例 可能 起作用:即,而不是“添加您的 {0}”,您需要一个更通用的模板,例如“添加您的 [女性] {0}”、“添加您的 [男性] {0}”等,所有这些都取决于语言 - 正如我说,这将很快成为一场噩梦。字符串应该尽可能简单且易于翻译 - 翻译人员的时间通常比开发人员花费在整理本地化问题和实施关键解决方案上的时间便宜。

标签: c# .net resx


【解决方案1】:

我并没有为您的问题指出解决方案,但是我对您的字符串格式存在疑虑:

您的示例的一个问题是使用 String.Format 进行翻译。

在某些语言中,“添加您的 {0}”部分将需要不同的措辞,具体取决于将插入 {0} 部分的内容。

一个例子:

“Add you horse”将翻译成丹麦语,变成“Tilføj din hest”,而“Add your donkey”将翻译成“Tilføj dit æsel”。 如您所见,存在差异:din/dit 无法从“添加您的 {0}”中正确翻译。 德语等其他语言也是如此。


编辑: 伪答案可能类似于: 为每个主题添加更多字符串到每个 resx 文件(使用 AddYourItemHorse、AddYourItemRacecar 和 AddYourItemDonkey 等标识符)。或者创建像 PageName.Racecar.da-DK.resx 这样的资源文件,其中包含赛车主题的资源等等。 然后,根据代码区域、主题和当前文化,您可以执行以下操作:

Dictionary<string, string> resourceDictionary = new Dictionary<string, string>();
private void fillDictionary(string path)
{
    using (ResXResourceReader rxrr = new ResXResourceReader(path))
    {
        foreach (DictionaryEntry entry in rxrr)
        {
            //Fill the fillDictionary
        }
    }
}

然后通过将您想要的内容与代表主题的字符串连接来访问字典中的字符串:

string theme = "Racecar";
Label testLabel = new Label();
testLabel.Text = resourceDictionary[AddYourItem + theme];

或者,您可以拥有一个资源文件 pr。区域、语言和主题,例如: MainForm.Racecar.da-DK.resx 然后构建传递给 fillDictionary 的路径,如下所示:

string languageCode = Thread.CurrentThread.CurrentCulture.Name;
string path = "MainForm." + theme + "." + llanguageCode + ".resx";

并将路径传递给fillDictionary-method。

请注意,以上代码未经测试。我只是从我的脑海中写到这里。但它应该为您指明可能(不一定是最佳)解决方案的方向。

您可以在此处阅读有关 ResXResourceReader 的更多信息:Working with .resx Files Programmatically

【讨论】:

  • 而这正是问题所在。因此,每个项目都有特定的字符串,因为“æsel”和“hest”获取各自的资源文件,都是丹麦语。有些语言的语法甚至比丹麦语还要糟糕!
  • 其实,这并不全是坏事!你让我意识到解决问题的一些新方法!与您刚才描述的方法非常接近;)
  • 我很高兴听到!请务必为遇到相同问题的其他人说明您的解决方案。
  • 我们将编写一个自定义类来处理资源文件并将它们合并并在应用程序加载时将它们保存在内存中。这似乎是最合适的方法。我只是希望它以某种方式得到支持而不必破解它:) 感谢您的投入,绝对值得!
猜你喜欢
  • 1970-01-01
  • 2015-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多