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

いろいろ備忘録日記

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

Linq入門記-91 (LINQ to XML, 行番号と行位置の取得, IXmlLineInfo, HasLineInfo, LineNumber, LinePosition)

C# Linq


LINQ to XMLでの行番号と行位置情報の取得について.

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


今回は、IXmlLineInfoを利用して行番号と行位置の情報を取得する方法についてです.
IXmlLineInfoはXObjectにて明示的実装が行われているインターフェースです.
IXmlLineInfo型にキャストすることで、値を取得できるようになります.


尚、行番号などを取得する場合は、予め対象のXMLをロードする際に
LoadOptions.SetLineInfoを設定してロードしておく必要があります.


LoadOptions.SetLineInfoを設定せずにロードした状態で、IXmlLineInfoの情報を取得しても行番号は常に0となります.


以下、サンプルです。

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

  #region LinqSamples-87
  /// <summary>
  /// LINQ to XMLのサンプルです.
  /// </summary>
  /// <remarks>
  /// IXmlLineInfoインターフェースから行番号を取得するサンプルです。
  /// </remarks>
  public class LinqSamples87 : IExecutable
  {
    public void Execute()
    {
      //
      // IXmlLineInfo
      //   IXmlLineInfoはXObjectにて明示的実装が行われているインターフェースである.
      //   IXmlLineInfo型にキャストすることで、値を取得できるようになる。
      //   このインターフェースには以下のメソッドとプロパティが定義されている.
      //     ■ HasLineInfoメソッド:行情報を持っているか否か.
      //     ■ LineNumberプロパティ:行番号
      //     ■ LinePositionプロパティ:行位置
      //
      //   尚、行番号などを取得する場合は、予め対象のXMLをロードする際に
      //   LoadOptions.SetLineInfoを設定してロードしておく必要がある。
      //   LoadOptions.SetLineInfoを設定せずにロードした状態で、IXmlLineInfoの
      //   情報を取得しても行番号は常に0となる.
      //
      var root = BuildSampleXml();

      foreach (var elem in root.Descendants())
      {
        var info = elem as IXmlLineInfo;

        Console.WriteLine(elem.Name);
        Console.WriteLine("\tHasLineInfo  == {0}", info.HasLineInfo());
        Console.WriteLine("\tLineNumber   == {0}", info.LineNumber);
        Console.WriteLine("\tLinePosition == {0}", info.LinePosition);
      }

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

      //
      // 要素を追加.
      //
      var newElem = new XElement("NewElement", "NewElementValue");
      root.Add(newElem);

      //
      // 再度行番号を表示.
      //   新規追加した要素からは行番号情報が取得出来ない.
      //
      foreach (var elem in root.Descendants())
      {
        var info = elem as IXmlLineInfo;

        Console.WriteLine(elem.Name);
        Console.WriteLine("\tHasLineInfo  == {0}", info.HasLineInfo());
        Console.WriteLine("\tLineNumber   == {0}", info.LineNumber);
        Console.WriteLine("\tLinePosition == {0}", info.LinePosition);
      }

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

    XElement BuildSampleXml()
    {
      //
      // サンプルXMLファイル
      //  see: http://msdn.microsoft.com/ja-jp/library/vstudio/ms256479(v=vs.90).aspx
      //
      // 行番号を取得するためにLoadOptions.SetLineInfoを設定.
      return XElement.Load(@"xml/Books.xml", LoadOptions.SetLineInfo);
    }
  }
  #endregion
}


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

  Book
        HasLineInfo  == True
        LineNumber   == 3
        LinePosition == 5
  Author
        HasLineInfo  == True
        LineNumber   == 4
        LinePosition == 8
  Title
        HasLineInfo  == True
        LineNumber   == 5
        LinePosition == 8
  Genre
        HasLineInfo  == True
        LineNumber   == 6
        LinePosition == 8
  Price
        HasLineInfo  == True
        LineNumber   == 7
        LinePosition == 8
  PublishDate
        HasLineInfo  == True
        LineNumber   == 8
        LinePosition == 8
  Description
        HasLineInfo  == True
        LineNumber   == 9
        LinePosition == 8
  Book
        HasLineInfo  == True
        LineNumber   == 12
        LinePosition == 5
  Author
        HasLineInfo  == True
        LineNumber   == 13
        LinePosition == 8
  Title
        HasLineInfo  == True
        LineNumber   == 14
        LinePosition == 8
  Genre
        HasLineInfo  == True
        LineNumber   == 15
        LinePosition == 8
  Price
        HasLineInfo  == True
        LineNumber   == 16
        LinePosition == 8
  PublishDate
        HasLineInfo  == True
        LineNumber   == 17
        LinePosition == 8
  Description
        HasLineInfo  == True
        LineNumber   == 18
        LinePosition == 8
  =========================================================
  Book
        HasLineInfo  == True
        LineNumber   == 3
        LinePosition == 5
  Author
        HasLineInfo  == True
        LineNumber   == 4
        LinePosition == 8
  Title
        HasLineInfo  == True
        LineNumber   == 5
        LinePosition == 8
  Genre
        HasLineInfo  == True
        LineNumber   == 6
        LinePosition == 8
  Price
        HasLineInfo  == True
        LineNumber   == 7
        LinePosition == 8
  PublishDate
        HasLineInfo  == True
        LineNumber   == 8
        LinePosition == 8
  Description
        HasLineInfo  == True
        LineNumber   == 9
        LinePosition == 8
  Book
        HasLineInfo  == True
        LineNumber   == 12
        LinePosition == 5
  Author
        HasLineInfo  == True
        LineNumber   == 13
        LinePosition == 8
  Title
        HasLineInfo  == True
        LineNumber   == 14
        LinePosition == 8
  Genre
        HasLineInfo  == True
        LineNumber   == 15
        LinePosition == 8
  Price
        HasLineInfo  == True
        LineNumber   == 16
        LinePosition == 8
  PublishDate
        HasLineInfo  == True
        LineNumber   == 17
        LinePosition == 8
  Description
        HasLineInfo  == True
        LineNumber   == 18
        LinePosition == 8
  NewElement
        HasLineInfo  == False
        LineNumber   == 0
        LinePosition == 0
  =========================================================


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

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

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