title: C# XSLT Transforming Large XML Files Quickly
body: <p>I'm transforming a > 2GB file with a lookup template in the XSLT.
  I would like this to run faster but can't find any low hanging fruit to improve performance. Any help would be greatly appreciated.
  I'm a newb when it comes to transformations.</p>
  
  <p>This is the current format of the XML file.</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
  &lt;contacts&gt;
      &lt;contact&gt;
          &lt;attribute&gt;
              &lt;name&gt;text12&lt;/name&gt;
              &lt;value&gt;B00085590&lt;/value&gt;
          &lt;/attribute&gt;
          &lt;attribute&gt;
              &lt;name&gt;text34&lt;/name&gt;
              &lt;value&gt;Atomos&lt;/value&gt;
          &lt;/attribute&gt;
          &lt;attribute&gt;
              &lt;name&gt;date866&lt;/name&gt;
              &lt;value&gt;02/21/1991&lt;/value&gt;
          &lt;/attribute&gt;
      &lt;/contact&gt;
      &lt;contact&gt;
          &lt;attribute&gt;
              &lt;name&gt;text12&lt;/name&gt;
              &lt;value&gt;B00058478&lt;/value&gt;
          &lt;/attribute&gt;
          &lt;attribute&gt;
              &lt;name&gt;text34&lt;/name&gt;
              &lt;value&gt;Balderas&lt;/value&gt;
          &lt;/attribute&gt;
          &lt;attribute&gt;
              &lt;name&gt;date866&lt;/name&gt;
              &lt;value&gt;11/24/1997&lt;/value&gt;
          &lt;/attribute&gt;
      &lt;/contact&gt;
  &lt;/contacts&gt;
  </code></pre>
  
  <p>The xslt I used for the transformation.</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
  &gt;
      &lt;xsl:output method="xml" indent="yes"/&gt;
  
  
      &lt;!--Identify location of the lookup xml--&gt;
      &lt;xsl:param name="lookupDoc" select="document('C:\Projects\Attributes.xml')" /&gt;  
  
      &lt;!--Main Template--&gt;
      &lt;xsl:template match="/contacts"&gt;        
  
              &lt;!--Apply Formatted Contacts Template--&gt;
              &lt;xsl:apply-templates select="contact" /&gt;            
  
      &lt;/xsl:template&gt;
  
      &lt;!--Formatted Contacts Template--&gt;
      &lt;xsl:template match="contact"&gt;
          &lt;contact&gt;
              &lt;xsl:for-each select="attribute"&gt;
                  &lt;!--Create variable to hold New Name after passing the Data Name to the Lookup Template--&gt;
                  &lt;xsl:variable name="newName"&gt;
                      &lt;xsl:apply-templates select="$lookupDoc/attributes/attribute"&gt;
                          &lt;xsl:with-param name="nameToMatch" select="name" /&gt;
                      &lt;/xsl:apply-templates&gt;
                  &lt;/xsl:variable&gt;     
                  &lt;!--Format Contact Element with New Name variable--&gt;
                  &lt;xsl:element name="{$newName}"&gt;
                      &lt;xsl:value-of select="value"/&gt;
                  &lt;/xsl:element&gt;          
              &lt;/xsl:for-each&gt;
          &lt;/contact&gt;
      &lt;/xsl:template&gt;
  
      &lt;!--Lookup Template--&gt;
      &lt;xsl:template match="attributes/attribute"&gt;
          &lt;xsl:param name="nameToMatch" /&gt;            
              &lt;xsl:value-of select='translate(translate(self::node()[name = $nameToMatch]/mappingname, "()*%$#@!~&amp;lt;&amp;gt;&amp;apos;&amp;amp;,.?[]=-+/\:1234567890", "")," ","")' /&gt;
          &lt;/xsl:template&gt;
  
  
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>Sample Lookup XML</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
  &lt;attributes&gt;
      &lt;attribute&gt;
          &lt;name&gt;text12&lt;/name&gt;
          &lt;mappingname&gt;ID&lt;/mappingname&gt;
          &lt;datatype&gt;Varchar2&lt;/datatype&gt;
          &lt;size&gt;30&lt;/size&gt;
      &lt;/attribute&gt;
      &lt;attribute&gt;
          &lt;name&gt;text34&lt;/name&gt;
          &lt;mappingname&gt;Last Name&lt;/mappingname&gt;
          &lt;datatype&gt;Varchar2&lt;/datatype&gt;
          &lt;size&gt;30&lt;/size&gt;
      &lt;/attribute&gt;
      &lt;attribute&gt;
          &lt;name&gt;date866&lt;/name&gt;
          &lt;mappingname&gt;DOB&lt;/mappingname&gt;
          &lt;datatype&gt;Date&lt;/datatype&gt;
          &lt;size&gt;&lt;/size&gt;
      &lt;/attribute&gt;
  &lt;/attributes&gt;
  </code></pre>
  
  <p>Transformed XML</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
  &lt;contacts&gt;
      &lt;contact&gt;
          &lt;ID&gt;B00085590&lt;/ID&gt;
          &lt;LastName&gt;Brady&lt;/LastName&gt;
          &lt;DOB&gt;02/21/1991&lt;/DOB&gt;
      &lt;/contact&gt;
      &lt;contact&gt;
          &lt;ID&gt;B00058478&lt;/ID&gt;
          &lt;LastName&gt;Balderas&lt;/LastName&gt;
          &lt;DOB&gt;11/24/1997&lt;/DOB&gt;
      &lt;/contact&gt;
  &lt;/contacts&gt;
  </code></pre>
  
  <p>C#</p>
  
  <pre><code>XsltSettings settings = new XsltSettings(true, true);
  XslCompiledTransform ContactsXslt = new XslCompiledTransform();
  ContactsXslt.Load(@"C:\Projects\ContactFormat.xslt", settings, new XmlUrlResolver());
  
  using (XmlReader r = XmlReader.Create(@"C:\Projects\Contacts.xml")){
     using (XmlWriter w = XmlWriter.Create(@"C:\Projects\FormattedContacts.xml")) {
        w.WriteStartElement("contacts");
        while (r.Read()) {                        
           if (r.NodeType == XmlNodeType.Element &amp;&amp; r.Name == "contact") {
              XmlReader temp = new XmlTextReader(new StringReader(r.ReadOuterXml()));                                
              ContactsXslt.Transform(temp, null, w);                            
           }
        }                        
     }
  }
  </code></pre>
  
  <p>The approach I'm taking is transforming 1 node at a time to avoid an OutOfMemoryException. Should I be feeding larger chunks through to speed up the process? Or am I going about this all wrong?</p>