私は同じ問題を抱えており、明らかに簡単な解決策はありません。
そこで、2 つの読み取り専用 FileStream を操作することにしました。1 つは XmlReader 用、もう 1 つは各行の位置を取得するためです。
private void ReadXmlWithLineOffset()
{
string malformedXml = "<test>\n<test2>\r <test3><test4>\r\n<test5>Thi is\r\ra\ntest</test5></test4></test3></test2>";
string fileName = "test.xml";
File.WriteAllText(fileName, malformedXml);
XmlTextReader xr = new XmlTextReader(new FileStream(fileName, FileMode.Open, FileAccess.Read));
FileStream fs2 = new FileStream(fileName, FileMode.Open, FileAccess.Read);
try
{
int currentLine = 1;
while(xr.Read())
{
if (!string.IsNullOrEmpty(xr.Name))
{
for (;currentLine < xr.LineNumber; currentLine++)
ReadLine(fs2);
Console.WriteLine("{0} : LineNum={1}, FileOffset={2}", xr.Name, xr.LineNumber, fs2.Position);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception : " + ex.Message);
}
finally
{
xr.Close();
fs2.Dispose();
}
}
private void ReadLine(FileStream fs)
{
int b;
while ((b = fs.ReadByte()) >= 0)
{
if (b == 10) // \n
return;
if (b == 13) // \r
{
if (fs.ReadByte() != 10) // if not \r\n, go back one byte
fs.Seek(-1, SeekOrigin.Current);
return;
}
}
}
2 つのリーダーを使用するため、これは最善の方法ではありません。これを回避するには、XmlReader と行カウンターの間で共有される新しい FileReader を書き直すことができます。タグの正確なオフセットを取得するには、LinePosition を使用する必要がありますが、エンコーディングのために注意が必要です。