ソフトウェア開発のグローバル化が進む今日、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 ファイルのコンテンツ構造は一定のルールと階層に従います。情報を整理するためには、3層構造を推奨します。
2.2.1. 第一層:Localization ノード
このノードには3つの重要なサブ属性が含まれます:
- 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. 第三層:言語キーノード
最終層は言語キーノードで、これらのノードには具体的な翻訳テキストが直接格納されます。例:
<?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>
実際のアプリケーションでは3層構造を推奨しますが、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. Avalonia における XML ファイルの具体的な応用実践
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. コード内での翻訳文字列の使用
コード内では、強タイプキーを使用して現在の言語カルチャの翻訳文字列を簡単に取得できます。例:
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# の強タイプ言語キー関連クラスの名前空間で、XML 言語ファイルの言語キーと関連付けるために使用されます。
以下はコントロールで翻訳テキストを使用する例です:
<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 インターフェースは動的なキーのバインディングもサポートしています。例:
<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 ファイルをマージする際には、以下の点に特に注意する必要があります:
- マージ前に必ずデータのバックアップを行い、マージ操作のミスによるデータの損失や破損を防ぎます。
- マージ前に各 XML のルートノードが同じであることを確認することを推奨します(例:すべて「Localization」と命名)。これにより、マージ後のファイル構造がより整然と統一されます。
- 異なるモジュールの XML ノードは重複を避ける必要があります。そうしないと、マージ中にデータの競合や上書きの問題が発生する可能性があります。
複数モジュールの XML ファイルマージの原理は非常にシンプルで、同じ言語サフィックスを持つ XML ファイルを一つのルートノードの下にマージし、言語データの統合と集中管理を実現します。
5.2. XML ファイルの編集
現在、XML ファイルの編集機能は比較的基本的であり、既存の言語の修正のみをサポートしています。

今後の開発計画では、XML ファイルの編集機能をさらに拡張し、以下の操作をサポートする予定です:
- Key の修正可能:既存の言語キーを修正できるようにし、プロジェクトのニーズの変化や誤ったキー命名の修正に対応します。
- Key の追加、Key の削除可能:柔軟なキー管理機能を提供し、ユーザーが実際の必要に応じて新しい言語キーを追加したり、不要になったキーを削除できるようにし、XML ファイルの内容をより正確かつ効率的にします。
- 言語の追加、言語の削除可能:キーの管理に加えて、新しい言語の追加や不要な言語の削除もサポートし、XML ファイルの国際化サポート範囲をさらに拡大します。
- ワンクリック翻訳:高度な 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 リソースファイルの適用シナリオ
- プロジェクトにユーザー側での修正要件がない場合、Resx リソースファイルは開発環境での管理のしやすさから、Resx Manager などのツールを使用して効率的に操作でき、理想的な選択肢です。
- 開発プロセスにおけるリソースファイル管理の効率を重視し、ユーザーが言語コンテンツを調整する必要がないプロジェクトには、Resx リソースファイルが非常に適しており、プロジェクトの国際化をスムーズに進めることができます。
6.2. カスタム XML ファイルの優位性
- プロジェクトにユーザー側での修正要件がある場合、カスタム XML ファイルは真価を発揮します。ユーザーは自身の使用シーンや言語習慣に応じてソフトウェアの言語コンテンツを柔軟に調整でき、ユーザーエクスペリエンスとソフトウェアの適応性が大幅に向上します。
- AI 編集を活用した言語処理が必要な場合、XML ファイルの形式は AI ツールとの連携が容易で、AI 技術の利点を最大限に活用し、効率的な翻訳と言語管理を実現できます。
- 明確で秩序ある言語構造管理を重視し、チームコラボレーション、コードメンテナンス、プロジェクト拡張を容易にしたいプロジェクトには、カスタム XML ファイルの名前空間組織方式と柔軟なノード構造が強力なサポートを提供します。
本記事では、Avalonia でカスタム XML ファイルを使用して国際化を実現する全プロセスについて詳しく説明しました。XML ファイルの作成、強タイプ生成、Avalonia での具体的な応用、言語管理機能などを含みます。同時に、開発者がこの国際化ソリューションを迅速に習得し、熟练に使用できるように、豊富なコード例、詳細な操作手順、関連する画像説明を提供しています。記事内で言及されている関連リソースは以下の通りです:
- XML 言語管理パッケージ:AvaloniaXmlTranslator
- サンプルデモと言語管理ツール:CodeWF.Toolbox
- Resx リソース管理拡張:Resx Manager
今後、技術の継続的な発展とアプリケーションシーンの多様化に伴い、Avalonia の国際化実装方法も進化し、洗練されていくでしょう。より便利で効率的なツールや技術が登場し、国際化開発プロセスをさらに簡素化し、ソフトウェアのグローバル品質を向上させ、ユーザーに優れた多言語体験を提供することを期待しています。Resx リソースファイルもカスタム XML ファイルも、それぞれの適用分野で引き続き重要な役割を果たし、Avalonia の国際化プロセスを共に推進していくでしょう。