だるろぐ

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

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

オープン拡張辞書を Windows Runtime アプリで読み書きする(3) - だるろぐ でオープン拡張辞書の読み込みは成功したので、今度は書き込み。

public static async void Save(string filename)
{
    XNamespace ns1 = "http://www.microsoft.com/ime/dctx";

    var xml = new XDocument(
        new XDeclaration("1.0", "utf-8", "yes"),
        new XComment("Build by Open Extended Dictionary Editor for WinRT"),
        new XElement(ns1 + "Dictionary", new XAttribute(XNamespace.Xmlns + "ns1", ns1),
            new XElement(ns1 + "DictionaryHeader",
                new XElement(ns1 + "DictionaryGUID", dictionary.DictionaryGuid),
                new XElement(ns1 + "DictionaryLanguage", dictionary.DictionaryLanguage),
                new XElement(ns1 + "DictionaryVersion", dictionary.DictionaryVersion),
                new XElement(ns1 + "CommentInsertion", dictionary.CommentInsertion),
                dictionary.DictionaryInfo.Select(_ => new XElement(ns1 + "DictionaryInfo",
                    new XAttribute("Language", _.Key),
                    new XElement(ns1 + "ShortName", _.Value.ShortName),
                    new XElement(ns1 + "LongName", _.Value.LongName),
                    new XElement(ns1 + "Description", _.Value.Description),
                    new XElement(ns1 + "Copyright", _.Value.Copyright)
                ))
            ),
            dictionary.DictionaryEntries.Select(_ => new XElement(ns1 + "DictionaryEntry",
                new XElement(ns1 + "PartOfSpeech", _.PartOfSpeech),
                new XElement(ns1 + "OutputString", _.OutputString),
                new XElement(ns1 + "InputString", _.InputString),
                new XElement(ns1 + "Priority", _.Priority),
                new XElement(ns1 + "ReverseConversion", _.ReverseConversion),
                new XElement(ns1 + "CommonWord", _.CommonWord)
            ))
        )
    );

    var file = await DownloadsFolder.CreateFileAsync(filename, CreationCollisionOption.GenerateUniqueName);
    var stream = await file.OpenStreamForWriteAsync();
    xml.Save(stream);
}

割とエレガントに書けたような気がする(あ、Stream って Dispose() とかしなきゃダメなのかな……あとで調べてもう一度書き直そう)。

ポイントは

new XElement(ns1 + "Dictionary", new XAttribute(XNamespace.Xmlns + "ns1", ns1),

の部分。 new XAttribute(XNamespace.Xmlns + "ns1", ns1を省くと

<!--Build by Open Extended Dictionary Editor for WinRT-->
<Dictionary xmlns="http://www.microsoft.com/ime/dctx">
    <DictionaryHeader>

となってしまい失敗(?、イケるのかもしれないけど、サンプルとは違う形式になる)。

<!--Build by Open Extended Dictionary Editor for WinRT-->
<ns1:Dictionary xmlns:ns1="http://www.microsoft.com/ime/dctx">
    <ns1:DictionaryHeader>

こんな感じにするには、明示的に XML Namespace の属性を足してやることが必要になる。

ちなみに開発のほうは共有コントラクトで選択テキストを辞書に追加……っていうところまではできたのだけど、ユーザーインターフェイスを作りこむのが面倒になって開発は止まってる。お盆休みに取り組むことにしよう。