PRB: XSL Transformations with XmlDataDocument May Perform More Slowly Than XPathDocument

Article translations Article translations
Article ID: 318580 - View products that this article applies to.
This article was previously published under Q318580
This article has been archived. It is offered "as is" and will no longer be updated.
Expand all | Collapse all

On This Page


XSL transformations (XSLT) with System.Xml.XmlDataDocument may run more slowly than XSLT with XPathDocument or XmlDocument.


XmlDataDocument is primarily designed to act as the bridge between the DataSet and XML.


Run XSL transformations by using the XmlDocument or XPathDocument classes instead of XmlDataDocument. Microsoft recommends that you use XPathDocument, because it is highly optimized for XSL transformations. See the "More Information" section of this article for a code sample that uses the XPathDocument.


This behavior is by design. The XmlDataDocument class is primarily designed for synchronizing XML with DataSet. Microsoft is looking into improving its performance for transformations in the next major release of Visual Studio .NET.

More information

The following is a Visual Basic .NET code sample that shows you how to apply XSL transformations on a DataSet by using the XPathDocument class. The sample initially loads the data from the Customers table and the Order table of the Northwind database into to a DataSet, and then the DataSet is transformed with the XmlDataDocument and XPathDocument classes.

Steps to Reproduce the Behavior

  1. Create a new Visual Basic .NET Console application project.
  2. Copy and paste the following into a file, and then save the file as Transform.xsl in the bin directory of the application:
    <xsl:stylesheet xmlns:xsl="" version="1.0">
    <xsl:template match="CustomerOrders">
      BODY {font-family:verdana;font-size:9pt}
      TD   {font-size:8pt}
        <TABLE BORDER="1">
          <xsl:apply-templates select="Customers"/>
    <xsl:template match="Customers">
          <xsl:value-of select="ContactName"/>, <xsl:value-of select="Phone"/><BR/>
          <xsl:apply-templates select="Orders"/>
    <xsl:template match="Orders">
      <TABLE BORDER="1">
        <TR><TD valign="top"><B>Order:</B></TD><TD valign="top"><xsl:value-of select="OrderID"/></TD></TR>
        <TR><TD valign="top"><B>Date:</B></TD><TD valign="top"><xsl:value-of select="OrderDate"/></TD></TR>
        <TR><TD valign="top"><B>Ship To:</B></TD>
            <TD valign="top"><xsl:value-of select="ShipName"/><BR/>
            <xsl:value-of select="ShipAddress"/><BR/>
            <xsl:value-of select="ShipCity"/>, <xsl:value-of select="ShipRegion"/>  <xsl:value-of select="ShipPostalCode"/><BR/>
            <xsl:value-of select="ShipCountry"/></TD></TR>
  3. Replace the code in Module1.vb file with the following.
    Imports System.IO
    Imports System.Data
    Imports System.Data.SqlClient
    Imports System.Xml
    Imports System.Xml.Xsl
    Imports System.Xml.XPath
    Module Module1
       Sub Main()
             ' Fill a DataSet with data from Customers and Orders tables of northwind database
             Dim nwindConn As SqlConnection = New SqlConnection("Password=;User ID=sa;Initial Catalog=Northwind;Data Source=localhost")
             Dim myDataSet As DataSet = New DataSet("CustomerOrders")
             Dim custDA As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Customers", nwindConn)
             custDA.Fill(myDataSet, "Customers")
             Dim ordersDA As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Orders", nwindConn)
             ordersDA.Fill(myDataSet, "Orders")
             myDataSet.Relations.Add("CustOrders", _
                                     myDataSet.Tables("Customers").Columns("CustomerID"), _
                                     myDataSet.Tables("Orders").Columns("CustomerID")).Nested = True
             ' Load the stylesheet 
             Dim xslTran As XslTransform = New XslTransform()
             ' Create a writer to stream the results to a file
             Dim writer As XmlTextWriter = New XmlTextWriter("xslt_output.html", System.Text.Encoding.UTF8)
             ' I. Transform the DataSet data with XmlDataDocument
             Dim startTime As DateTime
             ' Synchronize an XmlDataDocument with the DataSet
             Dim xmlDataDoc As XmlDataDocument = New XmlDataDocument(myDataSet)
             startTime = DateTime.Now
             xslTran.Transform(xmlDataDoc, Nothing, writer)
             Console.WriteLine("Time taken with XmlDataDocument: " + ((DateTime.Now).Subtract(startTime)).TotalSeconds.ToString())
             ' II. WORKAROUND: Use XPathDocument to transform the DataSet data
             Dim xpathDoc As XPathDocument = New XPathDocument(New StringReader(myDataSet.GetXml()))
             startTime = DateTime.Now
             xslTran.Transform(xpathDoc, Nothing, writer)
             Console.WriteLine("Time taken with XPathDocument  : " + ((DateTime.Now).Subtract(startTime)).TotalSeconds.ToString() + vbNewLine)
          Catch e As Exception
             Console.WriteLine("{0}", e.Message)
          End Try
       End Sub
    End Module
  4. Modify the connection string to suit your database settings. Compile and run the application. Read the inline comments to understand the functionality of the code.


For more information, click the links below to view the Software Developer Kit (SDK) documentation and the Microsoft Knowledge Base articles:
313651 ROADMAP for XML in the .NET Framework
To view the Software Developer Kit (SDK) documentation, visit the following Microsoft Web site:
System.Xml Namespace


Article ID: 318580 - Last Review: October 26, 2013 - Revision: 3.0
Applies to
  • Microsoft .NET Framework 1.0
kbnosurvey kbarchive kbbcl kbprb KB318580

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from