在xml标记中本地化值

本文关键字:本地化 xml | 更新日期: 2023-09-27 18:22:02

这是对整个代码流的概述。

FormatCode.xml是具有这种格式的输入文件之一。

<FormatCode id="405">
<Map>
<enumvalue>0</enumvalue> 
<actualvalue>Off</actualvalue>
</Map>
<Map>
<enumvalue>1</enumvalue> 
<actualvalue>Band1</actualvalue>
</Map>
<Map>
<enumvalue>2</enumvalue> 
<actualvalue>Band2</actualvalue>
</Map>
<Map>
<enumvalue>3</enumvalue> 
<actualvalue>Band3</actualvalue>
</Map>
 </FormatCode>

我的应用程序将该xml文件中的值读取到模型中的以下CLR对象中。其他xml文件也用作类中某些字段的输入,但我们不必担心。

public class parameter
{
    public string ParameterName
    {
        get;
        set;
    }
    public string Enumvalue
    {
        get;
        set;
    }
    public string CurrentValue
    {
        get;
        set;
    }
}

这通常通过视图模型进入xaml。

 <TextBlock x:Name="FnNameLbl" Text="{Binding Path=ParameterName}" >
 <ComboBox ItemSource="{binding protset}" displaymemeberpath="{binding path=current Value}">

protset是ObservableCollection。

现在,像submit、apply这样的UI标签已经通过resx文件进行了本地化。

我的问题是,将formatcode.xml中的值本地化为英语、德语、中文等等的最佳方式是什么

频带1波段2

我看到的示例主要处理与ui相关的标签和内容的本地化。尽管在这种情况下,我们在一定程度上处理ui,但它的价值来自于必须本地化的业务流程。

在xml标记中本地化值

您尝试过使用绑定转换器吗?以下是我使用的内容,以及执行实际翻译的翻译字符串扩展程序。

public class LocalizeConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is string)
        {
            return ((string)value).Translate(culture);
        }
        return null;
    }
    public object ConvertBack(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is string)
        {
            return (string)value;
        }
        return null;
    }
}

我在下面包含了使用xml文件进行本地化的代码。您甚至可以交互式地更新xml。Chooser只是一个对话框,我们用来向用户显示一个选项列表。它的实现是琐碎的,而且不包括在内。TextEntry与此类似,它是一个接受用户输入的对话框。

在我的基本窗口类中,我添加了一个TextInput侦听器来捕获CTRL+T(更新翻译xml)或CTRL+I(交互式)。

window.TextInput += (sender, args) =>
{
    if (args.ControlText == "'x14") // Ctrl+T
    {
        "".Translate(true);
    }
    if (args.ControlText == "'x09") // Ctrl+I
    {
        "".Translate(true, true);
    }
};
public static class LocalExtensions
{
    private static Dictionary<string,SortedDictionary<string,string>> languages = new Dictionary<string,SortedDictionary<string,string>>(5);
    private static bool autoAdd;
    public static bool interactiveAdd;
    public static string Translate(this String phrase, bool autoAdd, bool interactive = false)
    {
        var cultures = CultureInfo.GetCultures(CultureTypes.InstalledWin32Cultures);
        var chooser = new Chooser(Application.Current.Windows[0], "Translate from English To:", cultures.Select(culture => culture.EnglishName));
        chooser.ShowDialog();
        var selectedCulture = cultures.First(candidate => candidate.EnglishName == chooser.selectedItem);
        Localize.SetDefaultCulture(selectedCulture);
        LocalExtensions.autoAdd = autoAdd;
        LocalExtensions.interactiveAdd = interactive;
        return phrase.Translate();
    }
    public static string Translate(this String phrase)
    {
        return phrase.Translate(CultureInfo.CurrentCulture);
    }
    public static string Translate(this String phrase, CultureInfo culture) {
        if (String.IsNullOrWhiteSpace(phrase)) return phrase;

        var lang = culture.TwoLetterISOLanguageName;
        SortedDictionary<string,string> translations;
        if (!Directory.Exists(@"Languages"))
        {
            return phrase;
        }
        var pathName = FindFile("Languages''" + lang + ".xml");
        if ( !languages.ContainsKey(lang) ) {
            try {
                var xaml = File.ReadAllText(pathName, Encoding.UTF8);
                translations = (SortedDictionary<string, string>)XamlServices.Parse(xaml);
            } catch(Exception) {
                translations = new SortedDictionary<string,string>();
            }
            languages.Add(lang,translations);
        } else {
            translations = languages[lang];
        }
        if (translations.ContainsKey(phrase))
        {
            // return the translation for the specified phrase
            var tran = translations[phrase];
            var result = InteractiveUpdate(phrase, tran);
            if ( result != tran ) {
                translations[phrase] = result;
                SaveChanges(translations,pathName);
            }
            return translations[phrase];
        }
        // HACK: This is enabled by pressing CTRL+T on any window in the App.
        // Please note that any phrases in that window will not be translated
        // only phrases loaded in subsequent windows.
        if (LocalExtensions.autoAdd)
        {
            var result = InteractiveUpdate(phrase,phrase);
            translations.Add(phrase, result);
            SaveChanges(translations, pathName);
        }
        return phrase;
    }
    private static void SaveChanges(SortedDictionary<string,string> translations, string pathName)
    {
            var writer = new StreamWriter(pathName, false, Encoding.UTF8);
            XamlServices.Save(writer, translations);
            writer.Close();
    }
    private static string InteractiveUpdate(String phrase, String tran)
    {
        // HACK: Interactive update will be enabled by pressing CTRL+I on any window.
        // The same caveat applies here as with autoAdd above.
        if (interactiveAdd && !phrase.StartsWith("pack:"))
        {
            interactiveAdd = autoAdd = false;
            var tb = new TextBox
            {
                TextWrapping = TextWrapping.Wrap,
                AcceptsReturn = true,
                Height = double.NaN,
                Width = double.NaN,
                Text = tran
            };
            var te = new TextEntry(Application.Current.Windows[0],"Please translate:",tb,TextEntryType.AlphaNumeric);
            te.blurEnabled = false;
            te.ShowDialog();
            tran = tb.Text;
            interactiveAdd = autoAdd = true;
        }
        return tran;
    }
    private static string FindFile(string fileName)
    {
        var candidatePath = fileName;
        if (!File.Exists(fileName))
        {
            candidatePath = AppDomain.CurrentDomain.BaseDirectory + "''" + fileName;
            if (!File.Exists(candidatePath) && ApplicationDeployment.IsNetworkDeployed)
            {
                candidatePath = ApplicationDeployment.CurrentDeployment.DataDirectory + "''" + fileName;
            }
        }
        return candidatePath;
    }
}