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. 2732 Baker Blvd.Eugene OR 97403 USA Eugene OR 97403 USA =====================================Great Lakes Food Market Howard Snyder Marketing Manager (503) 555-7555 2732 Baker Blvd. 2732 Baker Blvd.Eugene OR 97403 USA Eugene OR 97403 USA =====================================2732 Baker Blvd. =====================================Eugene OR 97403 USA 44.95 Garghentini, Davide XML Developer's Guide Computer 44.95 2000-10-01 An in-depth look at creating applications with XML. ===================================== Garghentini, Davide XML 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 XML Developer's Guide Computer 44.95 2000-10-01 An in-depth look at creating applications with XML. ===================================== Garghentini, Davide XML 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 XML Developer's Guide Computer 44.95 2000-10-01 An in-depth look at creating applications with XML.
以下、参考リソースです.
- XElement.DescendantsAndSelf メソッド
- XElement.AncestorsAndSelf メソッド
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場