avalonia使用xml文件實現國際化

avalonia使用xml文件實現國際化

本文深入探討了 avalonia 使用 xml 文件實現國際化的方法與優勢。通過與 resx 資源文件對比,為開發者提供了選擇依據。xml 實現國際化適用於有用戶側修改需求、期望藉助 ai 編輯且追求清晰語言結構管理的場景。文中詳細居間了從創建語言文件、強類型生成到具體使用以及語言管理的整套流程,並提供了相關資源連結,如 xml 語言管理包、案例 demo 及語言管理工具、resx 資源管理擴展等,有助於開發者快速上手並在實際項目中應用該國際化方案,提升 avalonia 應用的全球化適配能力與用戶體驗。

最后更新 2024/12/23 下午12:34
沙漠尽头的狼
预计阅读 18 分钟
分类
Avalonia UI
标签
.NET C# Avalonia UI 國際化 本地化

在软件开发日益全球化的今天,Avalonia 的国际化实现策略成为了众多开发者关注的焦点。继上一篇 Avalonia 国际化之路:Resx 资源文件的深度应用与探索 之后,本文将引领大家深入探究如何运用自定义 XML 文件来达成 Avalonia 国际化的目标,开启一段全新的技术探索之旅。

1. xml 實現 avalonia ui 國際化的優勢剖析

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

resx 資源文件往往將維護權限局限於開發端,而自定義 xml 語言文件則以其獨特的靈活性脫穎而出。它能夠與可執行程式一同輸出,這一特性為用戶側的語言文件修改開闢了廣闊的空間。用戶不僅可以根據自身需求對已有語言內容進行調整,還能夠輕鬆地擴展更多語言種類,使軟體的國際化適應能力得到極大的提升,真正實現了從開發主導到用戶參與的轉變。

1.2.命名空間加持,結構清晰有序

自定義 xml 文件採用命名空間的方式來組織語言內容,這一設計理念與類的結構形成了精準的對應關係。通過這種方式,整個翻譯文件的架構變得清晰明了,易於管理與維護。無論是在大型項目中進行團隊協作開發,還是在後期的代碼維護與升級過程中,都能夠顯著提高工作效率,減少因結構混亂而可能引發的錯誤與困擾。

1.3. ai 翻譯便捷,助力語言轉換

在當今人工智慧蓬勃發展的時代,xml 文件在 ai 翻譯方面展現出了得天獨厚的優勢。藉助特定的工具或平台,我們可以方便地利用 ai 技術對 xml 翻譯文件進行處理。例如,只需提供簡單的提示詞,就能快速獲取多種語言版本的翻譯結果,為跨語言交流與軟體全球化推廣提供了強有力的支持。

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

2. xml 文件的創建與架構設計

2.1.精心規劃語言文件夾

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

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

以下是創建語言文件夾後的工程結構示例圖:

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

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.嚴謹構建 xml 文件內容

以下是上面一个 XML 文件内容(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>轻松实现一键翻译,支持多种语言互译,让沟通无界限!</Description>
	</PolyTranslateView>
	<Title2SlugView>
		<Title>AI一键转URL Slug</Title>
		<Description>轻松将中文、英文等文章标题一键转换成英文URL Slug。</Description>
	</Title2SlugView>
	<ChoiceLanguagesView>
		<LanguageKey>语言</LanguageKey>
		<Selectable>可选择的</Selectable>
		<Selected>已选择</Selected>
	</ChoiceLanguagesView>
</Localization>

xml 文件的內容結構遵循一定的規範與層次。推薦採用三層結構來組織信息:

2.2.1.第一層:localization 節點

此節點包含三個重要的子屬性:

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

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

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

<Localization language="Chinese (Simplified)" description="中文简体" cultureName="zh-CN">
  <!-- 此处将填充具体的模块和语言键值对 -->
</Localization>

2.2.2.第二層:功能名或類名節點

這一層以功能名或類名來命名節點,其目的在於對翻譯文件進行有效的功能歸類。例如,在一個包含 ai 模塊、轉換模塊等的項目中,可以分別創建 “aimodule”、“convertermodule” 等節點,將與各個模塊相關的翻譯內容分別放置在對應的節點下,使整個文件的結構更加清晰,便於管理與查找。

以下是一個包含多個模塊節點的 xml 文件示例:

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

<Localization language="Chinese (Simplified)" description="中文简体" cultureName="zh-CN">
  <AIModule>
    <!-- AI 模块相关的翻译内容 -->
  </AIModule>
  <ConverterModule>
    <!-- 转换模块相关的翻译内容 -->
  </ConverterModule>
</Localization>

2.2.3.第三層:語言 key 節點

最後一層為語言 key 節點,這些節點直接存儲了具體的翻譯文本內容。例如:

<?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>

在實際應用中,雖然推薦採用三層結構,但 xml 節點的嵌套層數並沒有嚴格的限制,開發者可以根據項目的實際需求和複雜程度進行靈活調整。例如:

<?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>轻松实现一键翻译,支持多种语言互译,让沟通无界限!</Description>
            </PolyTranslateView>
        </Baidu>
        <Google>
        	<PolyTranslateView>
                <Title>AI一键多语种翻译神器</Title>
                <Description>轻松实现一键翻译,支持多种语言互译,让沟通无界限!</Description>
            </PolyTranslateView>
        </Google>
    </Translate>
</Localization>

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

為了在代碼中更加方便、高效地使用 xml 翻譯文件,我們採用 t4 文件將 xml 轉換為 c# 的強類型。具體操作如下:

在 “i18n” 目錄下創建一個 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 文件並執行一次保存操作,系統將會自動生成或更新對應的 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";
    }
}
//...

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

4. xml 文件在 avalonia 中的具體應用實踐

4.1.安裝必備 nuget 包

Install-Package AvaloniaXmlTranslator

這一步驟將為我們的項目引入必要的功能組件,為後續的國際化操作奠定基礎。

4.2.動態獲取語言列表

在 avalonia 應用中,動態獲取程式配置的語言列表是實現國際化界面切換的關鍵步驟之一。通過以下代碼,我們可以輕鬆地獲取語言列表:

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;

    //...
}

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

4.3.動態切換語言

當用戶在界面中選擇了不同的語言後,我們需要在代碼中實現語言的動態切換。以下是實現語言切換的代碼示例:

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

這裡的 “language” 參數為 “localizationlanguage” 類的 “culturename” 屬性值,通過設置當前線程的文化信息,我們可以實現界面語言的即時切換,為用戶提供無縫的國際化體驗。

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

在代碼中,我們可以根據強類型 key 方便地獲取當前語言文化的翻譯字符串。例如:

var title = I18nManager.GetString(Localization.AskBotView.Title); // 获取当前语言
var titleZhCN = I18nManager.Instance.GetResource(Localization.Main.MainView.Title, "zh-CN");	// 获取中文简体
var titleEnUS = I18nManager.Instance.GetResource(Localization.Main.MainView.Title, "en-US");	// 获取英文

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

下面是代碼中綁定使用:

//...
 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 界面中的應用

在 axaml 界面中使用 xml 翻譯文件也非常便捷。首先,需要引入相應的命名空間:

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

其中,“markup” 為前面安裝的輔助庫命名空間,它提供了 “i18n” 標記擴展幫助類,用於在界面中綁定翻譯文本;“language” 為 t4 文件生成的 c# 強類型語言 key 關聯類命名空間,通過它可以與 xml 語言文件的語言 key 進行關聯。

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

<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” 標記擴展綁定到了 “choicelanguagesview.languagekey” 對應的翻譯文本上。這樣,當界面語言發生變化時,按鈕的顯示文本也會自動更新為相應語言的翻譯內容。

當然也支持指定語言:

<SelectableTextBlock u:FormItem.Label="Current Thread" Text="{markup:I18n {x:Static developModuleLanguage:Title2SlugView.Title}}" />
<SelectableTextBlock u:FormItem.Label="en-US" Text="{markup:I18n {x:Static developModuleLanguage:Title2SlugView.Title}, CultureName=en-US}" />
<SelectableTextBlock u:FormItem.Label="ja-JP" Text="{markup:I18n {x:Static developModuleLanguage:Title2SlugView.Title}, CultureName=ja-JP}" />
<SelectableTextBlock u:FormItem.Label="zh-CN" Text="{markup:I18n {x:Static developModuleLanguage:Title2SlugView.Title}, CultureName=zh-CN}" />
<SelectableTextBlock u:FormItem.Label="zh-Hant" Text="{markup:I18n {x:Static developModuleLanguage:Title2SlugView.Title}, CultureName=zh-Hant}" />

此外,axaml 界面還支持動態 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” 屬性分別綁定到了動態的 “selectedmenuitem.description” 和 “selectedmenuitem.name” 屬性上,通過 “i18n” 標記擴展實現了動態翻譯文本的顯示。

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

为了更好地管理 XML 语言文件,站长开发了部分管理功能,包括多模块 XML 文件合并与 XML 文件编辑,可点击下载 管理工具或自行编译 工具源码,工具程序结构如下:

5.1.多模塊 xml 文件合併

運行工具箱後,選擇 “xml 國際化管理” 下的 “xml 多模塊文件合併” 節點。默認情況下,將會打開工具箱自己的 “i18n” 目錄(點擊 “a” 可選擇其他語言目錄)。在界面的左側,將會顯示 xml 文件列表,點擊文件即可瀏覽其詳細內容。

在 “b” 處輸入合併後的 xml 文件前綴,默認值為 “localization”。然後,點擊 “c” 按鈕即可執行文件合併操作。以下是合併後的效果示例圖:

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

  1. 合併前務必進行數據備份,以防止因合併操作失誤而導致數據丟失或損壞。
  2. 建議在合併前確保每個 xml 根節點相同,例如都命名為 “localization”,這樣可以保證合併後的文件結構更加規範和統一。
  3. 不同模塊的 xml 節點應避免重複,否則可能會在合併過程中出現數據衝突或覆蓋的問題。

多模塊 xml 文件合併的原理其實非常簡單,即將相同語言後綴下的 xml 文件合併到一個根節點下,從而實現語言數據的整合與集中管理。

5.2. xml 文件編輯

目前,xml 文件編輯功能相對較為基礎,僅支持對現有的語言進行修改。

在後續的開發計劃中,站長將進一步完善 xml 文件編輯功能,預計將會支持以下操作:

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

5.3. ai 翻譯的巧妙應用

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

帮我将以下的中文简体 XML 翻译文件再翻译成中文繁体、英文、日语 3 个版本,不用回复其他文字,谢谢:

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

<Localization language="Chinese (Simplified)" description="中文简体" cultureName="zh-CN">
	<MainModule>
		<Title>碼坊工具箱</Title>
		<SearchToolTip>搜你所想</SearchToolTip>
		<WeChat>聯繫微信號:codewf</WeChat>
		<WeChatPublic>關注微信公眾號:dotnet9</WeChatPublic>
		<DesiredAvailabilityNotification>想要的都有,沒有請告知。</DesiredAvailabilityNotification>
		<AccessToolbox>訪問在線工具箱</AccessToolbox>
	<AboutView>
		<Title>關於</Title>
		<Description>本項目只用於學習使用</Description>
	</AboutView>
</Localization>
```

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

6. 總結與展望

在 avalonia 國際化的征程中,resx 資源文件和自定義 xml 文件是兩種重要的實現方式,開發者應根據具體需求進行合理選擇。

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

  1. 當項目無用戶側修改需求時,resx 資源文件憑藉其在開發環境中的便捷管理性,可通過 resx manager 等工具進行高效操作,是較為理想的選擇。
  2. 對於那些注重開發過程中資源文件管理效率,且不需要用戶參與語言內容調整的項目,resx 資源文件能夠很好地滿足需求,確保項目的國際化進程順利推進。

6.2.自定義 xml 文件的優勢領域

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

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

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

Keep Exploring

延伸阅读

更多文章