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

いろいろ備忘録日記

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

Linq入門記-83 (LINQ to XML, ナビゲーション, ElementsAfterSelf, ElementsBeforeSelf)

LINQ to XMLでのナビゲーション系のプロパティについて.

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


今回は兄弟要素を取得するElementsAfterSelfとElementsBeforeSelfです。
どちらもDescendantsAndSelf, AncestorsAndSelfメソッドと挙動が似ています。
違いは、兄弟要素を取得するという点です。


ElementsAfterSelf, ElementsBeforeSelfメソッドは、XNodeクラスに所属するメソッドです。
名前の通り自分自身も含めて結果を返してきます。


サンプルソースのコメントにも記述していますが、DescendantsAndSelfメソッドの時と同様に
こちらも、XNameを指定するオーバーロードを利用した場合に自分自身を含んでくれません・・・。


以下、サンプルです。

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

  #region LinqSamples-79
  /// <summary>
  /// LINQ to XMLのサンプルです.
  /// </summary>
  /// <remarks>
  /// ナビゲーション(ElementsAfterSelf, ElementsBeforeSelf)のサンプルです.
  /// </remarks>
  public class LinqSamples79 : IExecutable
  {
    public void Execute()
    {
      //
      // ElementsAfterSelf(), ElementsAfterSelf(XName)
      //   現在の要素の後ろにある兄弟要素を取得する.
      //   自分自身は含まない.
      //
      //   引数無し版のメソッドの方は、予想通りの動きをするが
      //   XNameを受け取るオーバーロードの方は、AncestorsAndSelf(XName)と
      //   同じ変な挙動をする。 (MSDNに乗っているサンプルでも、兄弟要素が表示されていない)
      //   謎,,,。
      //
      var root = BuildSampleXml();
      var startingPoint = root.Descendants("Book").First();

      // 最初のBook要素の後ろにある兄弟要素が表示される.
      foreach (var elem in startingPoint.ElementsAfterSelf())
      {
        Console.WriteLine(elem);
      }

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

      root = BuildSampleXml();
      startingPoint = root.Descendants("Title").Last();

      // Titleの後ろにある兄弟要素が表示される
      foreach (var elem in startingPoint.ElementsAfterSelf())
      {
        Console.WriteLine(elem);
      }


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

      root = BuildSampleXml();
      startingPoint = root.Descendants("Title").Last();

      // 何故か、引数に指定したGenreしか表示されない??
      // AncestorsAndSelf(XName)とかと同じ挙動.
      foreach (var elem in startingPoint.ElementsAfterSelf("Genre"))
      {
        Console.WriteLine(elem);
      }

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

      //
      // ElementsBeforeSelf(), ElementsBeforeSelf(XName)
      //   現在の要素の前にある兄弟要素を取得する.
      //   自分自身は含まない.
      //
      //   引数無し版のメソッドの方は、予想通りの動きをするが
      //   XNameを受け取るオーバーロードの方は、AncestorsAndSelf(XName)と
      //   同じ変な挙動をする。 (MSDNに乗っているサンプルでも、兄弟要素が表示されていない)
      //   謎,,,。
      //
      root = BuildSampleXml();
      startingPoint = root.Descendants("PublishDate").Last();

      foreach (var elem in startingPoint.ElementsBeforeSelf())
      {
        Console.WriteLine(elem);
      }

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

      root = BuildSampleXml();
      startingPoint = root.Descendants("Description").Last();

      // 何故か、引数に指定したPublishDateしか表示されない??
      // AncestorsAndSelf(XName)とかと同じ挙動.
      foreach (var elem in startingPoint.ElementsBeforeSelf("PublishDate"))
      {
        Console.WriteLine(elem);
      }

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

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


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

  
    Garcia, Debra
    Midnight Rain
    Fantasy
    5.95
    2000-12-16
    A former architect battles corporate zombies,
        an evil sorceress, and her own childhood to become queen
        of the world.
  
  =====================================
  Fantasy
  5.95
  2000-12-16
  A former architect battles corporate zombies,
        an evil sorceress, and her own childhood to become queen
        of the world.
  =====================================
  Fantasy
  =====================================
  Garcia, Debra
  Midnight Rain
  Fantasy
  5.95
  =====================================
  2000-12-16
  =====================================

以下、参考リソースです.

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

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