I want to read an xml file, apply a transform, then write to another file. The best way I can think of is this:
using (XmlTextReader reader = new XmlTextReader(new FileStream(_source, FileMode.Open))) using (XmlTextWriter writer = new XmlTextWriter(new StreamWriter(_destination))) { _xslTransform.Transform(reader, writer); }
But I really want to get a progress. If I’m just copying data I can do something like this (this might not be 100% right but something like this):
using (BinaryReader reader = new BinaryReader(new FileStream(_source, FileMode.Open))) using (BinaryWriter writer = new StreamWriter(_destination)) { byte[] buffer = new byte[2048]; int read = 0; int actual = 0; long total = reader.BaseStream.Length; while ((read = reader.Read(buffer, 0, buffer.Length)) > 0) { writer.Write(buffer, 0, read); actual = (actual <= total ? actual + read : read); updateProgress(Convert.ToInt32(actual / total * 100)); } }
So is there some way of doing this when using the XslCompiledTransform. I could just read it into memory first before writing to the file but I want to limit the amount of memory used, or does the XslCompiledTransform load it all into memory anyway?
I hope this makes some sort of sense, thanks!
Adam.
An option is to send xsl:message messages from within the transform and listen to these messages.
With this approach you have to run over the input document first and count the nodes that your transform ‘iterates’ over. This can be done using a very basic XSLT which just sends a message on every node of interest.
Then – during the actual transform – each time you hit a node of interest you can send an
progress message.
This message can be intercepted in the calling C# code with a message listener. You could put the following code into a small class for applying an XSL transform. It’s just a basic sample for illustrating; I hope you get the idea: