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
=========================================================
以下、参照リソースです。
- IXmlLineInfo インターフェイス
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場