読者です 読者をやめる 読者になる 読者になる

いろいろ備忘録日記

主に .NET と Python絡みのメモを公開しています。

Linq入門記-88 (LINQ to XML, イベント, Changing, Changed)


LINQ to XMLでのイベントの利用について.

過去の内容は以下から見れます。よろしければご参照くださいませ。


今回は、ChangingイベントとChangedイベントについて.
名前の通りですが、変更中にChangingイベント、変更後にChangedイベントが発生します。
どちらもWinFormsとかWPFとかのイベントと同じ感じです。


Changing, ChangedイベントのどちらもXObjectに所属します。
注意点として、イベントはXMLツリーの変更の場合のみ発生します。
XMLツリーを作成しているときは発生しないので注意です。


以下、サンプルです。

namespace Gsf.Samples
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Xml.Linq;

  #region LinqSamples-84
  /// <summary>
  /// LINQ to XMLのサンプルです.
  /// </summary>
  /// <remarks>
  /// Changing, Changedイベントについてのサンプルです。
  /// </remarks>
  public class LinqSamples84 : IExecutable
  {
    public void Execute()
    {
      //
      // Changing, Changedイベントは、どちらもXObjectに属するイベントである.
      //

      //
      // Changingイベント
      //   このイベントは、XMLツリーの変更によってのみ発生する。
      //   XMLツリーの作成では発生しないことに注意。
      // イベント引数として、XObjectChangeEventArgsを受け取る.
      // XObjectChangeEventArgsは、ObjectChangeというプロパティを持つ.      
      //
      var root = BuildSampleXml();

      root.Changing += OnNodeChanging;

      var book = root.Elements("Book").First();
      var title = book.Elements("Title").First();

      // 属性値を変更
      //   Changingイベントなので、イベントハンドラ内にて見えるsenderの値は*更新前*の値となる。 (Change)
      book.Attribute("id").Value = "updated";
      // 要素の値を変更
      //   Title要素は内部にXTextを持っているので、まずそれが削除される (Remove)
      //   その後、更新後の値を持つXTextが設定される. (Add)
      title.Value = "updated";
      title.Remove();
      // 要素を追加
      //   要素が追加される (Add)
      book.Add(new XElement("newelem", "hogehoge"));

      Console.WriteLine("=====================================");

      //
      // Changed
      //   このイベントは、XMLツリーの変更によってのみ発生する。
      //   XMLツリーの作成では発生しないことに注意。
      // イベント引数として、XObjectChangeEventArgsを受け取る.
      // XObjectChangeEventArgsは、ObjectChangeというプロパティを持つ.
      //
      root = BuildSampleXml();

      root.Changed += OnNodeChanged;

      book = root.Elements("Book").First();
      title = book.Elements("Title").First();

      // 属性値を変更
      //   Changedイベントなので、イベントハンドラ内にて見えるsenderの値は*更新後*の値となる。 (Change)
      book.Attribute("id").Value = "updated";
      title.Value = "updated";
      title.Remove();
      book.Add(new XElement("newelem", "hogehoge"));

      Console.WriteLine("=====================================");
    }

    // Changingイベントハンドラ
    void OnNodeChanging(object sender, XObjectChangeEventArgs e)
    {
      Console.WriteLine("Changing: sender--{0}:{1}, ObjectChange--{2}", sender.GetType().Name, sender, e.ObjectChange);
    }

    // Changedイベントハンドラ
    void OnNodeChanged(object sender, XObjectChangeEventArgs e)
    {
      Console.WriteLine("Changed: sender--{0}:{1}, ObjectChange--{2}", sender.GetType().Name, sender, e.ObjectChange);
    }

    XElement BuildSampleXml()
    {
      //
      // サンプルXMLファイル
      //  see: http://msdn.microsoft.com/ja-jp/library/vstudio/ms256479(v=vs.90).aspx
      //
      return XElement.Load(@"xml/Books.xml");
    }
  }
  #endregion
}


実行すると以下のようになります。

  Changing: sender--XAttribute:id="bk101", ObjectChange--Value
  Changing: sender--XText:XML Developer's Guide, ObjectChange--Remove
  Changing: sender--XText:updated, ObjectChange--Add
  Changing: sender--XElement:updated, ObjectChange--Remove
  Changing: sender--XElement:hogehoge, ObjectChange--Add
  =====================================
  Changed: sender--XAttribute:id="updated", ObjectChange--Value
  Changed: sender--XText:XML Developer's Guide, ObjectChange--Remove
  Changed: sender--XText:updated, ObjectChange--Add
  Changed: sender--XElement:updated, ObjectChange--Remove
  Changed: sender--XElement:hogehoge, ObjectChange--Add
  =====================================


以下、参照リソースです。

================================
過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。