Viper
Viper

Reputation: 2236

How to format a Xml-Stream for writing into file

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

Answers (1)

Richard
Richard

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

Related Questions