// ================================================================================================
//
// 言語間の対訳表をあらわすモデルクラスソース
//
//
// Copyright (C) 2012 Honeplus. All rights reserved.
//
// Honeplus
// ================================================================================================
namespace Honememo.Wptscs.Models
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;
using Honememo.Utilities;
///
/// 言語間の対訳表をあらわすモデルクラスです。
///
public class TranslationTable : List>, IXmlSerializable
{
#region プロパティ
///
/// 翻訳元言語コード。
///
/// の呼び出しを簡略化するためのプロパティ。
public string From
{
get;
set;
}
///
/// 翻訳先言語コード。
///
/// の呼び出しを簡略化するためのプロパティ。
public string To
{
get;
set;
}
#endregion
#region 公開メソッド
///
/// 指定された言語の対訳語を取得する。
///
/// 翻訳元言語コード。
/// 翻訳先言語コード。
/// 翻訳元語句。
/// 対訳語句。登録されていない場合 null。
/// , , のいずれかがnullの場合。
/// の大文字小文字は区別しない。
public string GetWord(string from, string to, string word)
{
// nullは不可。以降でエラーになるためここでチェック
Validate.NotNull(from, "from");
Validate.NotNull(to, "to");
string w = Validate.NotNull(word, "word").ToLower();
// 翻訳元言語の項目を探索
foreach (IDictionary record in this)
{
if (record.ContainsKey(from) && CollectionUtils.ContainsIgnoreCase(record[from], w))
{
// 翻訳元を発見した場合、それに対応する翻訳先の語句を返す
string s = null;
if (record.ContainsKey(to))
{
// 代表で先頭の値を取得
s = record[to].First();
}
return s;
}
}
return null;
}
///
/// 指定されている言語の組み合わせで対訳語を取得する。
///
/// 翻訳元語。
/// 対訳語。登録されていない場合 null。
/// , のいずれかが空の場合。
/// 大文字小文字は区別しない。
public string GetWord(string word)
{
if (string.IsNullOrEmpty(this.From) || string.IsNullOrEmpty(this.To))
{
throw new InvalidOperationException("empty from or to");
}
return this.GetWord(this.From, this.To, word);
}
#endregion
#region XMLシリアライズ用メソッド
///
/// シリアライズするXMLのスキーマ定義を返す。
///
/// XML表現を記述する。
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
///
/// XMLからオブジェクトをデシリアライズする。
///
/// デシリアライズ元の
public void ReadXml(XmlReader reader)
{
XmlDocument xml = new XmlDocument();
xml.Load(reader);
// ※ 以下、基本的に無かったらNGの部分はいちいちチェックしない。例外飛ばす
XmlElement tableElement = xml.DocumentElement;
// 各対訳の読み込み
this.Clear();
foreach (XmlNode recordNode in tableElement.SelectNodes("Group"))
{
IDictionary record = new Dictionary();
foreach (XmlNode wordNode in recordNode)
{
// 一つの言語に複数の値が登録可能なため、その場合配列に積む
XmlElement wordElement = wordNode as XmlElement;
string lang = wordElement.GetAttribute("Lang");
string word = wordElement.InnerText;
List list = new List();
string[] words;
if (record.TryGetValue(lang, out words))
{
list.AddRange(words);
}
// 既に登録されている場合、代表であれば先頭に、それ以外なら後ろに追加
bool head;
if (bool.TryParse(wordElement.GetAttribute("Head"), out head) && head)
{
list.Insert(0, word);
}
else
{
list.Add(word);
}
record[lang] = list.ToArray();
}
this.Add(record);
}
}
///
/// オブジェクトをXMLにシリアライズする。
///
/// シリアライズ先の
public void WriteXml(XmlWriter writer)
{
// 各対訳の出力
foreach (IDictionary record in this)
{
writer.WriteStartElement("Group");
foreach (KeyValuePair words in record)
{
bool first = true;
foreach (string word in words.Value)
{
writer.WriteStartElement("Word");
writer.WriteAttributeString("Lang", words.Key);
if (first && words.Value.Length > 1)
{
// 先頭項目は変換先として使用されるため、複数ある場合は代表フラグを出力
// ※ 2番目以降は同格のため、先頭以外の並び順は保障しない
writer.WriteAttributeString("Head", bool.TrueString);
first = false;
}
writer.WriteValue(word);
writer.WriteEndElement();
}
}
writer.WriteEndElement();
}
}
#endregion
}
}