だるろぐ

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

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

オープン拡張辞書を Windows Runtime アプリで読み書きする(1) - だるろぐ の続き。まずは第一の手段「XmlDocument を使う」で実装してみた。

public static async void Load(string path)
{
    var file = await Package.Current.InstalledLocation.GetFileAsync(path);
    var text = await Windows.Storage.FileIO.ReadTextAsync(file);

    var xml = new XmlDocument();
    var settings = new XmlLoadSettings();
    xml.LoadXml(text, settings);

    var dictionary = new OpenExtendedDictionary();

    dictionary.DictionaryGuid = xml.GetElementsByTagName("ns1:DictionaryGUID").First().InnerText;
    dictionary.DictionaryLanguage = xml.GetElementsByTagName("ns1:DictionaryLanguage").First().InnerText;
    dictionary.DictionaryVersion = xml.GetElementsByTagName("ns1:DictionaryVersion").First().InnerText;

    dictionary.DictionaryInfo.Language = xml.GetElementsByTagName("ns1:DictionaryInfo")[0].Attributes[0].NodeValue.AsString();
    dictionary.DictionaryInfo.ShortName = xml.GetElementsByTagName("ns1:ShortName").First().InnerText;
    dictionary.DictionaryInfo.LongName = xml.GetElementsByTagName("ns1:LongName").First().InnerText;
    dictionary.DictionaryInfo.Description = xml.GetElementsByTagName("ns1:Description").First().InnerText;
    dictionary.DictionaryInfo.Copyright = xml.GetElementsByTagName("ns1:Copyright").First().InnerText;

    dictionary.DictionaryEntries = xml.GetElementsByTagName("ns1:DictionaryEntry")
        .Select(entry => new OpenExtendedDictionaryEntry
        {
            PartOfSpeech = entry.ChildNodes.Where(_ => _.NodeName == "ns1:PartOfSpeech").First().InnerText,
            OutputString = entry.ChildNodes.Where(_ => _.NodeName == "ns1:OutputString").First().InnerText,
            InputString = entry.ChildNodes.Where(_ => _.NodeName == "ns1:InputString").First().InnerText,
            Priority = entry.ChildNodes.Where(_ => _.NodeName == "ns1:Priority").First().InnerText.AsInt(),
            ReverseConversion = entry.ChildNodes.Where(_ => _.NodeName == "ns1:ReverseConversion").First().InnerText.AsBool(),
            CommonWord = entry.ChildNodes.Where(_ => _.NodeName == "ns1:CommonWord").First().InnerText.AsBool(),
        })
        .ToObservableCollection();
}


書いてて辛かった。NameTable Class (System.Xml) | Microsoft Docs が IntelliSense で出てこないのはサポートされていないということだろうか。 GetElementsByTagName() とか ChildNodes.Where(_ => _.NodeName == "ns1:PartOfSpeech") とか、割とひどい感じだと思った。

過去の書き方
.NET 3.0 以前では、XmlDocument クラス(System.Xml 名前空間)を使っていました。

今の書き方
.NET 3.5 で、XDocument クラスが追加されました。 IEnumerable で要素一覧を読み出せるので、LINQ to Objects が使えます。

使わなくなった機能・新しい機能 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

おとなしく XDocument を使うことにしよう。