Reputation: 2236
I request a very large (>500mb) xml file from a web-service and write the contents of the ResponseStream
directly into a FileStream
. But when i open the resulting xml-file the contents look like this:
<Changes requestChangeTrackingId="-1" resultChangeTrackingId="2387">
<Selectors>
<Selector selectorId="1"><DateValidFrom>2000-01-01T00:00:00</DateValidFrom><DateValidTo>2099-12-31T00:00:00</DateValidTo><Code20Z>01A</Code20Z><CodeNUM/><CodeENT>1</CodeENT><ShortName>01A</ShortName></Selector>
<Selector selectorId="2"><DateValidFrom>2000-01-01T00:00:00</DateValidFrom><DateValidTo>2099-12-31T00:00:00</DateValidTo><Code20Z>01B</Code20Z><CodeNUM/><CodeENT>2</CodeENT><ShortName>01B</ShortName></Selector>
How can i format the stream so that it will look like this:
<Changes requestChangeTrackingId="-1" resultChangeTrackingId="2387">
<Selectors>
<Selector selectorId="1">
<DateValidFrom>2000-01-01T00:00:00</DateValidFrom>
<DateValidTo>2099-12-31T00:00:00</DateValidTo>
<Code20Z>01A</Code20Z>
<CodeNUM/>
<CodeENT>1</CodeENT>
<ShortName>01A</ShortName>
</Selector>
[...]
I cannot load the whole file into memory and therefore can't use a solution like
XDocument.Load( responseStream ).Save( "somefile.xml" );
Is there a way to pass a stream into some kind of XmlStreamFormatter and write the stream directly into the filesystem? The files to store can be so big that its not possible to always load the whole stream into memory and format it there.
Upvotes: 1
Views: 955
Reputation: 108975
XmlWriterSettings.Indent
provides the core of a mechanism here, so it a matter of ensuring that the whole content does not need to be loaded (but some careful testing with performance counters running is definitely advisable. Just one component too eager to read data in could lead to large address space and commit usage. Therefore with data sizes of the order of 500MB I would ensure this is built for x64 only—no AnyCPU builds.
So something like:
void FormatXmlToFile(FileStream input, string outputFile) {
using (var output = new FileStream(outputFile, FileMode.CreateNew)) {
var reader = XmlReader.Create(input);
var writerSettings = new XmlWriterSettings {
Indent = true
};
using (var writer = XmlWriter.Create(output, writerSettings)) {
writer.WriteNode(reader, true);
}
}
}
Upvotes: 1