What you can do is to take the basic logic of streaming an XmlReader
to an XmlWriter
from Mark Fussell's article Combining the XmlReader and XmlWriter classes for simple streaming transformations to transform your 3GB file into a modified file in which the <alias>
nodes have been relocated to the <name>
nodes. An example of using such streaming transformations is given in this answer to Automating replacing tables from external files.
Using that answer as a basis, grab the classes XmlReaderExtensions
, XmlWriterExtensions
, XmlStreamingEditorBase
and XmlStreamingEditor
from it and subclass XmlStreamingEditor
to create CustomerAliasXmlEditor
as follows:
class CustomerAliasXmlEditor : XmlStreamingEditor
{
// Confirm that the <customer> element is not in any namespace.
static readonly XNamespace customerNamespace = "";
public static void TransformFromTo(string fromFilePath, XmlReaderSettings readerSettings, string toFilePath, XmlWriterSettings writerSettings)
{
using (var xmlReader = XmlReader.Create(fromFilePath, readerSettings))
using (var xmlWriter = XmlWriter.Create(toFilePath, writerSettings))
{
new CustomerAliasXmlEditor(xmlReader, xmlWriter).Process();
}
}
public CustomerAliasXmlEditor(XmlReader reader, XmlWriter writer)
: base(reader, writer, ShouldTransform, Transform)
{
}
static bool ShouldTransform(XmlReader reader)
{
return reader.GetElementName() == customerNamespace + "customer";
}
static void Transform(XmlReader from, XmlWriter to)
{
var customer = XElement.Load(from);
var alias = customer.Element(customerNamespace + "alias");
if (alias != null)
{
var name = customer.Element(customerNamespace + "name");
if (name == null)
{
name = new XElement(customerNamespace + "name");
customer.Add(name);
}
alias.Remove();
name.Add(alias);
}
customer.WriteTo(to);
}
}
Then if fromFileName
is the name of your current 3GB XML file and toFileName
is the name of the file to which to output the transformed XML, you can do:
var readerSettings = new XmlReaderSettings { IgnoreWhitespace = true };
var writerSettings = new XmlWriterSettings { Indent = false}; // Or true if you prefer.
CustomerAliasXmlEditor.TransformFromTo(fromFileName, readerSettings, toFileName, writerSettings);
Sample working .Net fiddle showing that the XML
<Root>
<Item>
<SubItem>
<customer>
<name><first>Robert</first></name>
<alias>Rob</alias>
</customer>
</SubItem>
</Item>
<Item>
</Root>
Is transformed to
<Root>
<Item>
<SubItem>
<customer>
<name>
<first>Robert</first>
<alias>Rob</alias>
</name>
</customer>
</SubItem>
</Item>
<Item>
</Root>