だるろぐ

明日できることは、今日しない。

オープン拡張辞書を Windows Runtime アプリで読み書きする(3)

オープン拡張辞書を Windows Runtime アプリで読み書きする(2) - だるろぐ の続き。今度は第二の方法「XDocument を使う」でやってみる。

public static void Load(string path = @"Assets\Sample.dctx")
{
    var xml = XDocument.Load(Path.Combine(Package.Current.InstalledLocation.Path, path));
    XNamespace ns1 = "http://www.microsoft.com/ime/dctx";

    var header = xml.Root.Element(ns1 + "DictionaryHeader");
    dictionary.DictionaryGuid = header.Element(ns1 + "DictionaryGUID").Value;
    dictionary.DictionaryLanguage = header.Element(ns1 + "DictionaryLanguage").Value;
    dictionary.DictionaryVersion = header.Element(ns1 + "DictionaryVersion").Value;
    dictionary.DictionaryInfo = header.Elements(ns1 + "DictionaryInfo")
        .ToDictionary(
            _ => _.Attribute("Language").Value, 
            _ => new OpenExtendedDictionaryInfo()
            {
                ShortName = _.Element(ns1 + "ShortName").Value,
                LongName = _.Element(ns1 + "LongName").Value,
                Description = _.Element(ns1 + "Description").Value,
                Copyright = _.Element(ns1 + "Copyright").Value,
            }
        );

    dictionary.DictionaryEntries = xml.Root.Elements(ns1 + "DictionaryEntry")
        .Select(_ => new OpenExtendedDictionaryEntry
        {
            PartOfSpeech = _.Element(ns1 + "PartOfSpeech").Value,
            OutputString = _.Element(ns1 + "OutputString").Value,
            InputString = _.Element(ns1 + "InputString").Value,
            Priority = _.Element(ns1 + "Priority").Value.AsInt(),
            ReverseConversion = _.Element(ns1 + "ReverseConversion").Value.AsBool(),
            CommonWord = _.Element(ns1 + "CommonWord").Value.AsBool(),
        })
        .ToList();
}

個人的には XNamespace ns1 = "http://www.microsoft.com/ime/dctx";xml.Root.Element(ns1 + "DictionaryHeader") みたいなコードが気持ち悪いのだけど、XDocument では Namespace をこうやって扱うってことで割り切るしかない。

それ以外は割りとすっきりかけたので、DictionaruInfo たちは Dictionary<"ローケール文字列", DictionaryIndo> で管理するように書き換えてある。

public class OpenExtendedDictionary
{
    public OpenExtendedDictionary()
    {
        DictionaryInfo = new Dictionary<string,OpenExtendedDictionaryInfo>();
        DictionaryEntries = new List<OpenExtendedDictionaryEntry>();
    }

    public string DictionaryGuid { get; set; }
    public string DictionaryLanguage { get; set; }
    public string DictionaryVersion { get; set; }
    public bool CommentInsertion { get; set; }
    public Dictionary<string, OpenExtendedDictionaryInfo> DictionaryInfo { get; set; }
    public List<OpenExtendedDictionaryEntry> DictionaryEntries { get; set; }
}

public class OpenExtendedDictionaryInfo
{
    public string ShortName { get; set; }
    public string LongName { get; set; }
    public string Description { get; set; }
    public string Copyright { get; set; }
}

public class OpenExtendedDictionaryEntry
{
    public string PartOfSpeech { get; set; }
    public string OutputString { get; set; }
    public string InputString { get; set; }
    public int Priority { get; set; }
    public bool ReverseConversion { get; set; }
    public bool CommonWord { get; set; }
}

あと、ASP.NET WebPages みたいな .As***() 系の拡張メソッドが好きなので、別途作っておいた。

public static class ObjectExtentions
{
    public static string AsString(this object input, string defaultValue = "")
    {
        try
        {
            return input.ToString();
        }
        catch
        {
            return defaultValue;
        }
    }

    public static bool AsBool(this object input, bool defaultValue = false)
    {
        try
        {
            return Boolean.Parse(input.ToString());
        }
        catch
        {
            return defaultValue;
        }
    }

    public static int AsInt(this object input, int defaultValue = 0)
    {
        try
        {
            return int.Parse(input.ToString());
        }
        catch
        {
            return defaultValue;
        }
    }
}

別に Windows Runtime 関係なくなってきたな。

第三の手段、バインディングはやり方まったくわからないしめんどくさそうなので、今回は第二の手段をとることとし、今度は保存してみることにする。