Is it possible to reuse the same instance of XmlTextWriter class for generating more xml documents? I mean something like this:
XmlTextWriter writer = new XmlTextWriter();
writer.WriteStartDocument();
writer.WriteStartElement("Message1");
writer.WriteEndElement();
writer.WriteEndDocument();
// do something with xml created
...
writer.Reset() // ?
writer.WriteStartDocument();
writer.WriteStartElement("Message2");
writer.WriteEndElement();
writer.WriteEndDocument();
// do something with xml created
...
Easy answer: yes, it's possible to do that.
But this would be achived if underlying stream isn't pointing to a file. MemoryStream could be a good example of that.
As MemoryStream saves the stream "in memory", you can write a lot of XML files with your XmlTextWriter and after ending each document, do a MemoryStream.ToArray() and give it as argument for File.WriteAllBytes.
After writing all bytes, you'd clear your memory stream.
You can clear your memory stream by calling MemoryStream.SetLength method and give 0 as length:
Read more here, about stream overload of XmlTextWriter constructor:
And this for File.WriteAllBytes:
XmlTextWriter
Some years ago @NigelTouch raised a concern on some comment:
The problem I found is that if an exception is thrown part-way through, for example after WriteStartElement(), then even though you Flush() the Writer and set the Stream length to 0, the Writer remains in a WriteState of Element. When you start the next document, it begins with a closing ">" (for example). Avoid reuse
And some hours ago, @Mike-EEE got into the same issue:
Please provide working code of an example solution. I am running into the same problem as Nigel describes
BTW, a bit of trial-error got me to recover a given XmlTextWriter
to reuse it as many times as you want:
using(MemoryStream stream = new MemoryStream())
using(StreamReader streamReader = new StreamReader(stream))
using(XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8))
{
writer.WriteStartDocument(true);
writer.WriteStartElement("a");
try
{
throw new Exception();
}
catch
{
// This line makes de magic: ending the document
// avoids the issue mentioned by @NigelTouch
writer.WriteEndDocument();
writer.Flush();
stream.SetLength(0);
}
writer.WriteStartDocument(true);
writer.WriteStartElement("b");
writer.WriteEndElement();
writer.Flush();
stream.Position = 0;
Console.WriteLine(streamReader.ReadToEnd());
}