Tengo el mismo problema y aparentemente no hay una solución simple.
así que decidí manipular dos de sólo lectura FileStream: una para el XmlReader, el otro para obtener la posición de cada línea:
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;
}
}
}
Ésta no es la mejor forma de hacer esto, ya que utiliza dos lectores. Para evitar esto, podríamos reescribir un nuevo FileReader compartido entre XmlReader y el contador de líneas. Pero simplemente le da el desplazamiento de la línea que le interesa. Para obtener el desplazamiento exacto de la etiqueta, debemos usar LinePosition, pero esto puede ser complicado debido a la codificación.
¿Tuvo éxito con esto? Quiero hacer algo similar (calcular desviaciones de flujo de ciertos elementos, luego buscar ese desplazamiento y analizar a partir de allí), y lo mejor que puedo ver hasta ahora es analizar el archivo dos veces para calcular los desplazamientos. – Rob
@Rob Nope. Terminé usando XmlReader/XmlWriter para procesar el documento cada vez. Son lo suficientemente rápidos para mi propósito que puedo renunciar a esta optimización. – dmo