I have created an XMLReader
object out of a Stream
object which I was written to earlier by XMLWriter
object.
I know XMLReader
object is forward only and therefore I want to be able to save current reading position, so I will be able to continue read just from the place I stopped reading.
Is it possible?
I know it is maybe tricky, as XMLreader
read chunks of memory blocks so maybe it will be a problem to restore current XML element reading point.
Please advice only if you know for sure, it will work from your experience with this issue specifically.
Note :
1. I thought of simply saving the whole XMLReader
object reference for that scenario.
2. XMLReader
Position = current pointer to reading element not Stream.Position
as it is something else.
XmlReader provides forward-only, read-only access to XML data in a document or stream. This class conforms to the W3C Extensible Markup Language (XML) 1.0 (fourth edition) and the Namespaces in XML 1.0 (third edition) recommendations. XmlReader methods let you move through XML data and read the contents of a node.
C# XmlReader ReadThe Read method reads the next node from the stream. In this XML file, we have products. The example presents the classic approach to reading XML files. We read the document node by node and in the switch statement or expression deal with the particular element, text, attribute or other type of node.
IsStartElement(String) Calls MoveToContent() and tests if the current content node is a start tag or empty element tag and if the Name property of the element found matches the given argument.
Creates a new XmlReader instance using the specified stream with default settings. Creates a new XmlReader instance by using the specified URI and settings.
I work in a project where an external system writes xmls (without a defined namespace) and we need to read them to find nodes with some special values:
So, I think this code can help you:
var input1 = @"<root>
<ta>
<XGLi6id90>774825484.1418393</XGLi6id90>
<VAfrBVB>
<EG60sk>1030847709.7303829</EG60sk>
<XR>NOT_READY</XR>
</VAfrBVB>
</ta>
<DxshpR>1123</DxshpR>
var input2 = @"<root>
<ta>
<XGLi6id90>774825484.1418393</XGLi6id90>
<VAfrBVB>
<EG60sk>1030847709.7303829</EG60sk>
<XR>99999999</XR>
</VAfrBVB>
</ta>
<DxshpR>1123</DxshpR>
var stream1 = new MemoryStream(Encoding.UTF8.GetBytes(input1));
var stream2 = new MemoryStream(Encoding.UTF8.GetBytes(input2));
stream1.Position = 0;
stream2.Position = 0;
var position1 = DoWork(stream1, new Position());
var position2 = DoWork(stream2, position1);
public static Position DoWork(Stream stream, Position position)
{
using (XmlTextReader xmlTextReader = new XmlTextReader(stream))
{
using (XmlReader xmlReader = XmlReader.Create(xmlTextReader, xmlReaderSettings))
{
// restores the last position
xmlTextReader.SetPosition(position);
System.Diagnostics.Debug.WriteLine(xmlReader.Value); // Second time prints 99999999
while (xmlReader.Value != "NOT_READY" && xmlReader.Read())
{
// a custom logic to process nodes....
}
// saves the position to process later ...
position = xmlTextReader.GetPosition();
System.Diagnostics.Debug.WriteLine(xmlReader.Value); // First time prints NOT_READY
}
}
return position;
}
}
public class Position
{
public int LinePosition { get; set; }
public int LineNumber { get; set; }
}
public static class XmlReaderExtensions
{
public static void SetPosition(this XmlTextReader xmlTextReader, Position position)
{
if (position != null)
{
while (xmlTextReader.LineNumber < position.LineNumber && xmlTextReader.Read())
{
}
while (xmlTextReader.LinePosition < position.LinePosition && xmlTextReader.Read())
{
}
}
}
public static Position GetPosition(this XmlTextReader xmlTextReader)
{
Position output;
if (xmlTextReader.EOF)
{
output = new Position();
}
else
{
output = new Position { LineNumber = xmlTextReader.LineNumber, LinePosition = xmlTextReader.LinePosition };
}
return output;
}
}
Important and obviously, it will work only when the structure of the xml (line breaks, nodes, etc.) is always the same. In other case, it will not work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With