いろいろ備忘録日記

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

Linq入門記-81 (LINQ to XML, ナビゲーション, DescendantsAndSelf, AncestorsAndSelf)

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

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


今回は子孫要素を取得するDescendantsAndSelfメソッドと先祖要素を取得するAncestorsAndSelfメソッドです。
どちらもDescendantsメソッドとAncestorsメソッドとほとんど同じ動きをします。
違いは

結果のコレクションに自分自身も含めて返してくる。(なのでAndSelfとなっている)

という点です。


でも、正直、このメソッド未だに理解できない動きを私の中でしています・・・。
どういうことなのかは、サンプルソースの中に長々とコメントで記載しているのですが
何故か

XNameを指定して実行すると自分自身を含んでくれない

という結果になります。MSDNにのっているサンプル(http://msdn.microsoft.com/ja-jp/library/bb300437.aspx)も
そのようになっているので、恐らくこれが正しい動作なのだと思うんですが、、、。


引数無しのオーバーロードの方は、ちゃんと自分自身を含んで結果を返してくれます。


以下、サンプルです。

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

  #region LinqSamples-77
  /// <summary>
  /// LINQ to XMLのサンプルです.
  /// </summary>
  /// <remarks>
  /// ナビゲーション(DescendantsAndSelf, AncestorsAndSelfメソッド)のサンプルです.
  /// </remarks>
  public class LinqSamples77 : IExecutable
  {
    public void Execute()
    {
      //
      // DescendantsAndSelf
      //   自身とその子要素を取得するためのメソッド.
      //   引数が無い版とXNameを指定する版が存在する。
      //   引数無し版は、意図した通りの結果を返してくれるが
      //   XNameを指定する版のメソッドは、子要素を含めてくれない・・・。
      //   (指定の仕方が間違っているのか? 使い方が間違っているのか?)
      //
      //   恐らく、指定の仕方が間違っているのだと思うが、普段利用しないメソッドなので、これで一旦完了とする.
      //
      var root = BuildSampleXml();
      var startingPoint = root.Descendants("Customer").First();
      var descendantsAndSelf = startingPoint.DescendantsAndSelf();

      //
      // AndSelf付きのメソッドを利用しているので、Customer自身も結果に含まれる.
      //
      foreach (var elem in descendantsAndSelf)
      {
        Console.WriteLine(elem);
      }

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

      //
      // AndSelfを付けていないので、Customer自身は含まれない.
      //
      foreach (var elem in startingPoint.Descendants())
      {
        Console.WriteLine(elem);
      }

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

      //
      // XName付きのオーバーロードを呼び出すと、予想と違う結果となる
      // Customer要素が含まれない. (??)
      //
      // MSDNの説明には、「この要素とこの要素のすべての子要素」と記載があるが・・・。
      // (MSDNのメソッドページにあるサンプルプログラムの結果も、以下の結果と同じになっている)
      //
      //   恐らく、指定の仕方が間違っているのだと思うが、普段利用しないメソッドなので、これで一旦完了とする.
      //
      root = BuildSampleXml();
      startingPoint = root.Descendants("Customer").First();
      descendantsAndSelf = startingPoint.DescendantsAndSelf("FullAddress");

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

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

      //
      // AncestorsAndSelf
      //   自身とその先祖を取得するためのメソッド.
      //   引数が無い版とXNameを指定する版が存在する。
      //   引数無し版は、意図した通りの結果を返してくれるが
      //   XNameを指定する版のメソッドは、先祖を含めてくれない・・・。
      //   (指定の仕方が間違っているのか? 使い方が間違っているのか?)
      //
      root = BuildSampleXml2();
      startingPoint = root.Descendants("Price").First();

      var ancestorsAndSelf = startingPoint.AncestorsAndSelf();

      //
      // AndSelf付きのメソッドを利用しているので、Price自身も結果に含まれる.
      //
      foreach (var elem in ancestorsAndSelf)
      {
        Console.WriteLine(elem);
      }

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

      //
      // Price自身は含まれない
      //
      foreach (var elem in startingPoint.Ancestors())
      {
        Console.WriteLine(elem);
      }

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

      //
      // XName付きのオーバーロードを呼び出すと、予想と違う結果となる
      // Price要素が含まれない. (??)
      //
      // MSDNの説明には、「この要素とこの要素の先祖」と記載があるが・・・。
      // (MSDNのメソッドページにあるサンプルプログラムの結果も、以下の結果と同じになっている)
      //
      root = BuildSampleXml2();
      startingPoint = root.Descendants("Price").First();
      ancestorsAndSelf = startingPoint.AncestorsAndSelf("Book");

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

    XElement BuildSampleXml()
    {
      //
      // サンプルXMLファイル
      //  see: http://msdn.microsoft.com/ja-jp/library/vstudio/bb387025.aspx
      //
      return XElement.Load(@"xml/CustomersOrders.xml");
    }

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


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

  
    Great Lakes Food Market
    Howard Snyder
    Marketing Manager
    (503) 555-7555
    
      
2732 Baker Blvd.
Eugene OR 97403 USA
Great Lakes Food Market Howard Snyder Marketing Manager (503) 555-7555
2732 Baker Blvd.
Eugene OR 97403 USA
2732 Baker Blvd.
Eugene OR 97403 USA ===================================== Great Lakes Food Market Howard Snyder Marketing Manager (503) 555-7555
2732 Baker Blvd.
Eugene OR 97403 USA
2732 Baker Blvd.
Eugene OR 97403 USA =====================================
2732 Baker Blvd.
Eugene OR 97403 USA
===================================== 44.95 Garghentini, Davide <a class="keyword" href="http://d.hatena.ne.jp/keyword/XML">XML</a> Developer's Guide Computer 44.95 2000-10-01 An in-depth look at creating applications with XML. Garghentini, Davide <a class="keyword" href="http://d.hatena.ne.jp/keyword/XML">XML</a> Developer's Guide Computer 44.95 2000-10-01 An in-depth look at creating applications with XML. 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. ===================================== Garghentini, Davide <a class="keyword" href="http://d.hatena.ne.jp/keyword/XML">XML</a> Developer's Guide Computer 44.95 2000-10-01 An in-depth look at creating applications with XML. Garghentini, Davide <a class="keyword" href="http://d.hatena.ne.jp/keyword/XML">XML</a> Developer's Guide Computer 44.95 2000-10-01 An in-depth look at creating applications with XML. 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. ===================================== Garghentini, Davide <a class="keyword" href="http://d.hatena.ne.jp/keyword/XML">XML</a> Developer's Guide Computer 44.95 2000-10-01 An in-depth look at creating applications with XML.


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

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

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