Avalonia使用XML文件實現(xiàn)國際化

在軟件開發(fā)日益全球化的今天,Avalonia 的國際化實現(xiàn)策略成為了眾多開發(fā)者關(guān)注的焦點。繼上一篇 Avalonia 國際化之路:Resx 資源文件的深度應(yīng)用與探索之后,本文將引領(lǐng)大家深入探究如何運用自定義 XML 文件來達成 Avalonia 國際化的目標(biāo),開啟一段全新的技術(shù)探索之旅。

1. XML 實現(xiàn) Avalonia UI 國際化的優(yōu)勢剖析

1.1. 突破維護局限,擁抱用戶定制

Resx 資源文件往往將維護權(quán)限局限于開發(fā)端,而自定義 XML 語言文件則以其獨特的靈活性脫穎而出。它能夠與可執(zhí)行程序一同輸出,這一特性為用戶側(cè)的語言文件修改開辟了廣闊的空間。用戶不僅可以根據(jù)自身需求對已有語言內(nèi)容進行調(diào)整,還能夠輕松地擴展更多語言種類,使軟件的國際化適應(yīng)能力得到極大的提升,真正實現(xiàn)了從開發(fā)主導(dǎo)到用戶參與的轉(zhuǎn)變。

1.2. 命名空間加持,結(jié)構(gòu)清晰有序

自定義 XML 文件采用命名空間的方式來組織語言內(nèi)容,這一設(shè)計理念與類的結(jié)構(gòu)形成了精準(zhǔn)的對應(yīng)關(guān)系。通過這種方式,整個翻譯文件的架構(gòu)變得清晰明了,易于管理與維護。無論是在大型項目中進行團隊協(xié)作開發(fā),還是在后期的代碼維護與升級過程中,都能夠顯著提高工作效率,減少因結(jié)構(gòu)混亂而可能引發(fā)的錯誤與困擾。

1.3. AI 翻譯便捷,助力語言轉(zhuǎn)換

在當(dāng)今人工智能蓬勃發(fā)展的時代,XML 文件在 AI 翻譯方面展現(xiàn)出了得天獨厚的優(yōu)勢。借助特定的工具或平臺,我們可以方便地利用 AI 技術(shù)對 XML 翻譯文件進行處理。例如,只需提供簡單的提示詞,就能快速獲取多種語言版本的翻譯結(jié)果,為跨語言交流與軟件全球化推廣提供了強有力的支持。

下圖為輸出的XML語言文件:

0201.png

2. XML 文件的創(chuàng)建與架構(gòu)設(shè)計

2.1. 精心規(guī)劃語言文件夾

首先,我們需要創(chuàng)建一個專門用于存放語言文件的文件夾,例如命名為 “i18n”。在這個過程中,需要特別注意的是,相同輸出路徑下不同模塊的 XML 文件名必須保持唯一性。因為在程序編譯輸出時,如果存在同名的 XML 文件,將會導(dǎo)致文件替換,進而造成語言信息的丟失,這無疑會給國際化進程帶來嚴(yán)重的阻礙。

文件前綴可以工程名命名(方便區(qū)分),后綴為語言文化名

以下是創(chuàng)建語言文件夾后的工程結(jié)構(gòu)示例圖:

0202.png

編譯輸出后文件列表如下:

AIModule.en-US.xml
AIModule.ja-JP.xml
AIModule.zh-CN.xml
AIModule.zh-Hant.xml
ConverterModule.en-US.xml
ConverterModule.ja-JP.xml
ConverterModule.zh-CN.xml
ConverterModule.zh-Hant.xml
DevelopmentModule.en-US.xml
DevelopmentModule.ja-JP.xml
DevelopmentModule.zh-CN.xml
DevelopmentModule.zh-Hant.xml
MainModule.en-US.xml
MainModule.ja-JP.xml
MainModule.zh-CN.xml
MainModule.zh-Hant.xml
XmlTranslatorManagerModule.en-US.xml
XmlTranslatorManagerModule.ja-JP.xml
XmlTranslatorManagerModule.zh-CN.xml
XmlTranslatorManagerModule.zh-Hant.xml

2.2. 嚴(yán)謹(jǐn)構(gòu)建 XML 文件內(nèi)容

以下是上面一個XML文件內(nèi)容(AIModule.zh-CN.xml):

<?xml version="1.0" encoding="utf-8"?>

<Localization language="Chinese (Simplified)" description="中文簡體" cultureName="zh-CN">
    <AIModule>
        <Title>AI</Title>
    </AIModule>
    <AskBotView>
        <Title>智能問答助手</Title>
        <Description>一鍵提問,即刻獲取答案,智能問答助手為您解惑。</Description>
    </AskBotView>
    <PolyTranslateView>
        <Title>AI一鍵多語種翻譯神器</Title>
        <Description>輕松實現(xiàn)一鍵翻譯,支持多種語言互譯,讓溝通無界限!</Description>
    </PolyTranslateView>
    <Title2SlugView>
        <Title>AI一鍵轉(zhuǎn)URL Slug</Title>
        <Description>輕松將中文、英文等文章標(biāo)題一鍵轉(zhuǎn)換成英文URL Slug。</Description>
    </Title2SlugView>
    <ChoiceLanguagesView>
        <LanguageKey>語言</LanguageKey>
        <Selectable>可選擇的</Selectable>
        <Selected>已選擇</Selected>
    </ChoiceLanguagesView>
</Localization>

XML 文件的內(nèi)容結(jié)構(gòu)遵循一定的規(guī)范與層次。推薦采用三層結(jié)構(gòu)來組織信息:

2.2.1. 第一層:Localization 節(jié)點

此節(jié)點包含三個重要的子屬性:

  • language:用于明確指定語言的名稱,例如 “Chinese (Simplified)” 表示簡體中文。
  • description:對該語言的簡要描述,如 “中文簡體”,以便于開發(fā)者和用戶快速了解語言的基本特征。
  • cultureName:語言的文化名,這是一個在國際化處理中非常關(guān)鍵的標(biāo)識,例如 “zh-CN” 代表簡體中文的文化區(qū)域。如果對文化名不太清楚,可以通過百度搜索等方式獲取準(zhǔn)確信息。

以下是一個基本的 XML 文件框架示例:

<?xml version="1.0" encoding="utf-8"?>

<Localization language="Chinese (Simplified)" description="中文簡體" cultureName="zh-CN">
  <!-- 此處將填充具體的模塊和語言鍵值對 -->
</Localization>

2.2.2. 第二層:功能名或類名節(jié)點

這一層以功能名或類名來命名節(jié)點,其目的在于對翻譯文件進行有效的功能歸類。例如,在一個包含 AI 模塊、轉(zhuǎn)換模塊等的項目中,可以分別創(chuàng)建 “AIModule”、“ConverterModule” 等節(jié)點,將與各個模塊相關(guān)的翻譯內(nèi)容分別放置在對應(yīng)的節(jié)點下,使整個文件的結(jié)構(gòu)更加清晰,便于管理與查找。

以下是一個包含多個模塊節(jié)點的 XML 文件示例:

<?xml version="1.0" encoding="utf-8"?>

<Localization language="Chinese (Simplified)" description="中文簡體" cultureName="zh-CN">
  <AIModule>
    <!-- AI 模塊相關(guān)的翻譯內(nèi)容 -->
  </AIModule>
  <ConverterModule>
    <!-- 轉(zhuǎn)換模塊相關(guān)的翻譯內(nèi)容 -->
  </ConverterModule>
</Localization>

2.2.3. 第三層:語言 Key 節(jié)點

最后一層為語言 Key 節(jié)點,這些節(jié)點直接存儲了具體的翻譯文本內(nèi)容。例如:

<?xml version="1.0" encoding="utf-8"?>

<Localization language="Chinese (Simplified)" description="中文簡體" cultureName="zh-CN">
  <AIModule>
    <Title>AI</Title>
  </AIModule>
  <AskBotView>
    <Title>智能問答助手</Title>
    <Description>一鍵提問,即刻獲取答案,智能問答助手為您解惑。</Description>
  </AskBotView>
</Localization>

在實際應(yīng)用中,雖然推薦采用三層結(jié)構(gòu),但 XML 節(jié)點的嵌套層數(shù)并沒有嚴(yán)格的限制,開發(fā)者可以根據(jù)項目的實際需求和復(fù)雜程度進行靈活調(diào)整。例如:

<?xml version="1.0" encoding="utf-8"?>

<Localization language="Chinese (Simplified)" description="中文簡體" cultureName="zh-CN">
    <AIModule>
        <Title>AI</Title>
    </AIModule>
    <AI>
        <AskBotView>
            <Title>智能問答助手</Title>
            <Description>一鍵提問,即刻獲取答案,智能問答助手為您解惑。</Description>
        </AskBotView>
    </AI>
    <Translate>
        <Baidu>
            <PolyTranslateView>
                <Title>AI一鍵多語種翻譯神器</Title>
                <Description>輕松實現(xiàn)一鍵翻譯,支持多種語言互譯,讓溝通無界限!</Description>
            </PolyTranslateView>
        </Baidu>
        <Google>
            <PolyTranslateView>
                <Title>AI一鍵多語種翻譯神器</Title>
                <Description>輕松實現(xiàn)一鍵翻譯,支持多種語言互譯,讓溝通無界限!</Description>
            </PolyTranslateView>
        </Google>
    </Translate>
</Localization>

3. 語言文件的強類型生成策略

為了在代碼中更加方便、高效地使用 XML 翻譯文件,我們采用 T4 文件將 XML 轉(zhuǎn)換為 C# 的強類型。具體操作如下:

在 “i18n” 目錄下創(chuàng)建一個 T4 文件,例如命名為 “Language.tt”,并在其中填入以下代碼:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ import namespace="System.IO" #>
<#@ output extension=".cs" #>
//------------------------------------------------------------------------------  
// <auto-generated>  
//     This code was generated by a tool.  
//     Changes to this file may cause incorrect behavior and will be lost if  
//     the code is regenerated.  
// </auto-generated>  
//------------------------------------------------------------------------------
<#
    string templateDirectory = Path.GetDirectoryName(Host.TemplateFile);
    string xmlFilePath = Directory.GetFiles(templateDirectory, "*.xml").FirstOrDefault();
    if (xmlFilePath!= null)
    {
        XDocument xdoc = XDocument.Load(xmlFilePath);
        var classNodes = xdoc.Nodes().OfType<XElement>().DescendantsAndSelf().Where(e => e.Descendants().Count() == 0).Select(e => e.Parent).Distinct().ToList();
        foreach (var classNode in classNodes)
        {
            var namespaceSegments = classNode.Ancestors().Reverse().Select(node => node.Name.LocalName);
            string namespaceName = string.Join(".", namespaceSegments);
            GenerateClasses(classNode, namespaceName);
        }
    }
    else
    {
        Write("XML file not found, please ensure that there is an XML file in the current directory");
    }

    void GenerateClasses(XElement element, string namespaceName)
    {
        string className = element.Name.LocalName;
        StringBuilder classBuilder = new StringBuilder();
        classBuilder.AppendLine($"namespace {namespaceName}");
        classBuilder.AppendLine("{");
        classBuilder.AppendLine($"    public static class {className}");
        classBuilder.AppendLine("    {");
        var fieldNodes = element.Elements();
        foreach (var fieldNode in fieldNodes)
        {
            var propertyName = fieldNode.Name.LocalName;
            var languageKey = $"{namespaceName}.{className}.{propertyName}";
            classBuilder.AppendLine($"        public static readonly string {propertyName} = \"{languageKey}\";");
        }
        classBuilder.AppendLine("    }");
        classBuilder.AppendLine("}");
        Write(classBuilder.ToString());
    }
#>

每次對 XML 文件進行修改后,只需打開該 T4 文件并執(zhí)行一次保存操作,系統(tǒng)將會自動生成或更新對應(yīng)的 C# 類。例如:

//...
namespace Localization
{
    public static class AIModule
    {
        public static readonly string Title = "Localization.AIModule.Title";
    }
}
namespace Localization
{
    public static class AskBotView
    {
        public static readonly string Title = "Localization.AskBotView.Title";
        public static readonly string Description = "Localization.AskBotView.Description";
    }
}
//...

這些生成的強類型類將為我們在后續(xù)的代碼編寫中提供極大的便利,使我們能夠更加準(zhǔn)確、便捷地獲取和使用翻譯文本。

4. XML 文件在 Avalonia 中的具體應(yīng)用實踐

4.1. 安裝必備 NuGet 包

Install-Package AvaloniaXmlTranslator

這一步驟將為我們的項目引入必要的功能組件,為后續(xù)的國際化操作奠定基礎(chǔ)。

4.2. 動態(tài)獲取語言列表

在 Avalonia 應(yīng)用中,動態(tài)獲取程序配置的語言列表是實現(xiàn)國際化界面切換的關(guān)鍵步驟之一。通過以下代碼,我們可以輕松地獲取語言列表:

List<LocalizationLanguage> languages = I18nManager.Instance.Resources.Select(kvp => kvp.Value).ToList();

其中,“LocalizationLanguage” 類定義如下:

public class LocalizationLanguage
{
    public string Language { get; set; } = (string) null;

    public string Description { get; set; } = (string) null;

    public string CultureName { get; set; } = (string) null;

    //...
}

獲取到語言列表后,我們可以將其用于界面綁定,例如在下拉菜單中顯示可供用戶選擇的語言選項,或者在其他需要展示語言信息的界面元素中進行數(shù)據(jù)綁定。

4.3. 動態(tài)切換語言

當(dāng)用戶在界面中選擇了不同的語言后,我們需要在代碼中實現(xiàn)語言的動態(tài)切換。以下是實現(xiàn)語言切換的代碼示例:

var culture = new CultureInfo(language);
I18nManager.Instance.Culture = culture;

這里的 “l(fā)anguage” 參數(shù)為 “LocalizationLanguage” 類的 “CultureName” 屬性值,通過設(shè)置當(dāng)前線程的文化信息,我們可以實現(xiàn)界面語言的即時切換,為用戶提供無縫的國際化體驗。

4.4. 代碼中使用翻譯字符串

在代碼中,我們可以根據(jù)強類型 Key 方便地獲取當(dāng)前語言文化的翻譯字符串。例如:

var title = I18nManager.GetString(Localization.AskBotView.Title); // 如上,中文獲得字符串為“智能問答助手”

通過這種方式,我們可以在代碼的任何地方靈活地使用翻譯文本,確保界面顯示的內(nèi)容與用戶選擇的語言相匹配。

下輩是代碼中綁定使用:

//...
 var header = item is UserControl { DataContext: ITabItemBase tabItem }
     ? tabItem.TitleKey
     : item?.GetType().ToString();
 var newTabItem = new TabItem { Content = item };
 newTabItem.Bind(TabItem.HeaderProperty, new I18nBinding(header));
 regionTarget.Items.Add(newTabItem);
//...

4.5. Axaml 界面中的應(yīng)用

在 Axaml 界面中使用 XML 翻譯文件也非常便捷。首先,需要引入相應(yīng)的命名空間:

xmlns:language="clr-namespace:Localization"
xmlns:markup="https://codewf.com"

其中,“markup” 為前面安裝的輔助庫命名空間,它提供了 “I18n” 標(biāo)記擴展幫助類,用于在界面中綁定翻譯文本;“l(fā)anguage” 為 T4 文件生成的 C# 強類型語言 Key 關(guān)聯(lián)類命名空間,通過它可以與 XML 語言文件的語言 Key 進行關(guān)聯(lián)。

以下是在控件中使用翻譯文本的示例:

<Button
    Grid.Row="3"
    Grid.Column="1"
    Margin="10,0,0,0"
    HorizontalAlignment="Stretch"
    VerticalAlignment="Center"
    Command="{Binding RaiseChoiceLanguagesCommand}"
    Content="{markup:I18n {x:Static language:ChoiceLanguagesView.LanguageKey}}" />

在上述示例中,“Button” 控件的 “Content” 屬性通過 “I18n” 標(biāo)記擴展綁定到了 “ChoiceLanguagesView.LanguageKey” 對應(yīng)的翻譯文本上。這樣,當(dāng)界面語言發(fā)生變化時,按鈕的顯示文本也會自動更新為相應(yīng)語言的翻譯內(nèi)容。

此外,Axaml 界面還支持動態(tài) Key 的綁定,例如:

<u:Banner
    Classes.Bordered="{Binding Bordered}"
    Content="{markup:I18n {Binding SelectedMenuItem.Description}}"
    Header="{markup:I18n {Binding SelectedMenuItem.Name}}"
    Type="{Binding SelectedType}" />

在這個示例中,“Banner” 控件的 “Content” 和 “Header” 屬性分別綁定到了動態(tài)的 “SelectedMenuItem.Description” 和 “SelectedMenuItem.Name” 屬性上,通過 “I18n” 標(biāo)記擴展實現(xiàn)了動態(tài)翻譯文本的顯示。

5. 語言管理功能的深度解析

為了更好地管理 XML 語言文件,站長開發(fā)了部分管理功能,包括多模塊 XML 文件合并與 XML 文件編輯,可點擊下載 管理工具或自行編譯 工具源碼,工具程序結(jié)構(gòu)如下:

0203.png

5.1. 多模塊XML文件合并

運行工具箱后,選擇 “XML 國際化管理” 下的 “XML 多模塊文件合并” 節(jié)點。默認情況下,將會打開工具箱自己的 “I18n” 目錄(點擊 “A” 可選擇其他語言目錄)。在界面的左側(cè),將會顯示 XML 文件列表,點擊文件即可瀏覽其詳細內(nèi)容。

0204.png

在 “B” 處輸入合并后的 XML 文件前綴,默認值為 “Localization”。然后,點擊 “C” 按鈕即可執(zhí)行文件合并操作。以下是合并后的效果示例圖:

0205.png

在進行多模塊 XML 文件合并時,需要特別注意以下幾點:

  1. 合并前務(wù)必進行數(shù)據(jù)備份,以防止因合并操作失誤而導(dǎo)致數(shù)據(jù)丟失或損壞。
  2. 建議在合并前確保每個 XML 根節(jié)點相同,例如都命名為 “Localization”,這樣可以保證合并后的文件結(jié)構(gòu)更加規(guī)范和統(tǒng)一。
  3. 不同模塊的 XML 節(jié)點應(yīng)避免重復(fù),否則可能會在合并過程中出現(xiàn)數(shù)據(jù)沖突或覆蓋的問題。

多模塊 XML 文件合并的原理其實非常簡單,即將相同語言后綴下的 XML 文件合并到一個根節(jié)點下,從而實現(xiàn)語言數(shù)據(jù)的整合與集中管理。

5.2. XML 文件編輯

目前,XML 文件編輯功能相對較為基礎(chǔ),僅支持對現(xiàn)有的語言進行修改。

0206.png

在后續(xù)的開發(fā)計劃中,站長將進一步完善 XML 文件編輯功能,預(yù)計將會支持以下操作:

  1. 可修改 Key:允許用戶對已有的語言 Key 進行修改,以適應(yīng)項目需求的變化或修正錯誤的 Key 命名。
  2. 可添加 Key、刪除 Key:提供靈活的 Key 管理功能,用戶可以根據(jù)實際需要添加新的語言 Key 或刪除不再使用的 Key,使 XML 文件的內(nèi)容更加精準(zhǔn)和高效。
  3. 可添加語言、刪除語言:除了對 Key 的管理外,還將支持添加新的語言種類以及刪除不再需要的語言,進一步拓展 XML 文件的國際化支持范圍。
  4. 一鍵翻譯:借助先進的 AI 翻譯技術(shù),實現(xiàn)一鍵將 XML 文件中的內(nèi)容翻譯成多種語言,大大提高翻譯效率,減少人工翻譯的工作量和成本。

5.3. AI 翻譯的巧妙應(yīng)用

在 XML 文件的翻譯過程中,我們可以巧妙地利用 AI 翻譯技術(shù)來提高效率。例如,通過編寫如下提示詞:

幫我將以下的中文簡體XML翻譯文件再翻譯成中文繁體、英文、日語3個版本,不用回復(fù)其他文字,謝謝:

```xml
<?xml version="1.0" encoding="utf-8"?>

<Localization language="Chinese (Simplified)" description="中文簡體" cultureName="zh-CN">
    <MainModule>
        <Title>碼界工坊工具箱</Title>
        <SearchToolTip>搜你所想</SearchToolTip>
        <WeChat>聯(lián)系微信號:codewf</WeChat>
        <WeChatPublic>關(guān)注微信公眾號:Dotnet9</WeChatPublic>
        <DesiredAvailabilityNotification>想要的都有,沒有請告知。</DesiredAvailabilityNotification>
        <AccessToolbox>訪問在線工具箱</AccessToolbox>
    <AboutView>
        <Title>關(guān)于</Title>
        <Description>本項目只用于學(xué)習(xí)使用</Description>
    </AboutView>
</Localization>
```

將上述 XML 內(nèi)容提供給 AI,即可獲取相應(yīng)的中文繁體、英文、日語翻譯版本,為國際化工作提供了快速且便捷的翻譯途徑,效果顯著,如同以下示例圖展示:

0207.gif

6. 總結(jié)與展望

在 Avalonia 國際化的征程中,Resx 資源文件和自定義 XML 文件是兩種重要的實現(xiàn)方式,開發(fā)者應(yīng)根據(jù)具體需求進行合理選擇。

6.1. Resx 資源文件的適用場景

  1. 當(dāng)項目無用戶側(cè)修改需求時,Resx 資源文件憑借其在開發(fā)環(huán)境中的便捷管理性,可通過 Resx Manager 等工具進行高效操作,是較為理想的選擇。
  2. 對于那些注重開發(fā)過程中資源文件管理效率,且不需要用戶參與語言內(nèi)容調(diào)整的項目,Resx 資源文件能夠很好地滿足需求,確保項目的國際化進程順利推進。

6.2. 自定義 XML 文件的優(yōu)勢領(lǐng)域

  1. 若項目存在用戶側(cè)修改需求,自定義 XML 文件則能夠大放異彩。它允許用戶根據(jù)自身使用場景和語言習(xí)慣對軟件的語言內(nèi)容進行靈活調(diào)整,極大地提升了用戶體驗和軟件的適應(yīng)性。
  2. 在需要借助 AI 編輯進行語言處理的情況下,XML 文件的格式更易于與 AI 工具進行交互,能夠充分利用 AI 技術(shù)的優(yōu)勢,實現(xiàn)高效的翻譯和語言管理。
  3. 對于追求清晰、有序的語言結(jié)構(gòu)管理,以便于團隊協(xié)作、代碼維護和項目擴展的項目,自定義 XML 文件的命名空間組織方式和靈活的節(jié)點結(jié)構(gòu)能夠提供強有力的支持。

本文詳細闡述了 Avalonia 使用自定義 XML 文件實現(xiàn)國際化的全過程,包括 XML 文件的創(chuàng)建、強類型生成、在 Avalonia 中的具體應(yīng)用以及語言管理功能等方面。同時,為開發(fā)者提供了豐富的代碼示例、詳細的操作步驟以及相關(guān)的圖片說明,旨在幫助開發(fā)者快速上手并熟練運用這一國際化方案。文中涉及的相關(guān)資源如下:

展望未來,隨著技術(shù)的不斷發(fā)展和應(yīng)用場景的日益豐富,Avalonia 國際化的實現(xiàn)方式也將不斷演進和完善。我們期待能夠看到更多便捷、高效的工具和技術(shù)涌現(xiàn),進一步簡化國際化開發(fā)流程,提升軟件的全球化品質(zhì),為用戶帶來更加卓越的跨語言使用體驗。無論是 Resx 資源文件還是自定義 XML 文件,都將在各自的適用領(lǐng)域繼續(xù)發(fā)揮重要作用,共同推動 Avalonia 國際化進程的不斷前進。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容