XSLT XML transformation vs Object mapping

By admin - Last updated: Monday, February 9, 2009 - Save & Share - One Comment

I’ve run some tests on transformation from one XML schema to the other so that I can compare the performance between XSLT and XmlSerializer with object mapping as well as the Pros and Cons.
It appears XSLT transformed my source XML to target XML faster than the object mapping since XSLT doesn’t take the type of the elements or attribute into account, objects initialization within .NET is a relatively expensive procedure. The properties defined within the Developer class contains int, string, string[] and a complex type. The picture below shows the source schema and target schema.
xslt
The goal is to transform Developers XML into People XML.
The source XML snippet I used

<?xml version="1.0" encoding="utf-8"?>
<Developers>
  <Developer>
    <Name>name 0</Name>
    <Skills>
      <string>skill10</string>
      <string>skill20</string>
      <string>skill30</string>
    </Skills>
    <Address>
      <Street>Porland0</Street>
      <City>City0</City>
    </Address>
  </Developer>
  <Developer>
    <Name>name 1</Name>
    <Skills>
      <string>skill11</string>
      <string>skill21</string>
      <string>skill31</string>
    </Skills>
    <Address>
      <Street>Porland1</Street>
      <City>City1</City>
    </Address>
  </Developer>
</Developers>

target schema XML snippet

<?xml version="1.0" encoding="utf-8"?>
<People>
  <Person>
    <Name>name 0</Name>
    <Description>skill10,skill20,skill20</Description>
    <Address>City0 Porland0</Address>
  </Person>
  <Person>
    <Name>name 1</Name>
    <Description>skill11,skill21,skill21</Description>
    <Address>City1 Porland1</Address>
  </Person>
</People>

Basically, Skills property as array of string from Developer object will become a string property in Person. Address property from Developer object will become a string property in Person.

The main method which performs the test,

/// <summary>
/// 1) Generates sample xml.
/// 2) Performs object mapping.
/// 3) Performs Xslt mapping.
/// </summary>
static void Main(string[] args)
{
    // generate sample developer xml
    GenerateDevelopersXml(999999);

    // use object mapping to obtain person xml
    ObjectMap();
    // use Xslt to obtain person xml
    XsltMap();
    Console.ReadLine();
}

/// <summary>
/// Mapps Developer objects to Person objects to create
/// Person xml by serialization.
/// </summary>
static void ObjectMap()
{
    DateTime start = DateTime.Now;
    // deserialize from xml.
    // check out FromXml Extension method.
    List<Developer> developers =
new List<Developer>().FromXml("Developers", "Developers.xml");
    List<Person> people = new List<Person>();
    // iterate through the developers and create new mapped person objects
    foreach (Developer dev in developers)
    {
        people.Add(
            new Person
            {
                Name = dev.Name,
                Description = dev.Skills == null
? null : string.Join(",", dev.Skills),
                Address = dev.Address == null
? null : (string.Concat(dev.Address.Street, ",", dev.Address.City))
            });
    }
    // serialize list of person to xml, check out ToXml extension method
    people.ToXml("People", "PeopleByObjMap.xml");
    Console.WriteLine("Object mapping total sec: {0}",
(DateTime.Now - start).TotalSeconds);
}

/// <summary>
/// Xslt transform Developer xml to Person xml
/// </summary>
static void XsltMap()
{
    DateTime start = DateTime.Now;
    // uses ToPersonXml.xslt to transform the xml
    XslCompiledTransform xslt = new XslCompiledTransform(false);
    // load the xsl
    xslt.Load("ToPersonXml.xslt");
    // perform transform
    xslt.Transform("Developers.xml", "PeopleByXslt.xml");
    Console.WriteLine("Xslt mapping total sec: {0}",
(DateTime.Now - start).TotalSeconds);
}

The output from above tests shows,
———————————————————————
Object mapping total sec: 15.53125
Xslt mapping total sec: 11.328125
———————————————————————
Xslt is faster than object mapping, 4+ seconds difference.

What if we unassign Address and Skills properties for Developer object,
———————————————————————
Object mapping total sec: 3.765625
Xslt mapping total sec: 3.359375
———————————————————————
Interestingly, they both improved the performance. Obviously, object mapping improved significantly because there are no string concatenation and complex object initialization.
Still, XSLT has done it faster. Let’s see the XML transformed in this test,

Transformed by object mapping and serialization,

<Person>
    <Name>name 0</Name>
    <Description xsi:nil="true" />
    <Address xsi:nil="true" />
  </Person>
Transformed by Xslt,
<-- transformed by Xslt -->
  <Person>
    <Name>name 1</Name>
    <Description /> <!-- note here it is "" but not null -->
    <Address /><!-- note here it is "" but not null -->
  </Person>

The Xslt transformed the nullable properties as a empty string, this is definitely not desired because there should have extra handle for nullable elements in the XSLT. In this case it doesn’t.
This is just example of demonstrating the chance of user error in XSLT is much higher than object mapping method.

In conclusion, from performance point of view, XSLT transforms XML much faster and more efficient than object serialization and mapping.
However, object serialization and mapping ensure the type and schema safety of the XML infoset, therefore, it minimizes the chance of user errors.

XSLT snippet used to see Developers.xml in HTML browser,

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0">
  <xsl:output method="html" indent="yes" />
  <xsl:include href="Part1.xslt"/>
  <xsl:template name="main" match="@* | node()">

    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <title>XSLT Test</title>
        <style type="text/css">
          table th
          {
          background-color: #CCFF66;
          }
          table td
          {
          border-width: 1px;
          border-style: solid;
          }
        </style>
      </head>
      <body>
        <h1>Developers</h1>
        <table>
          <tr>
            <xsl:for-each select="Developer[1]/*">
              <xsl:call-template name="header">
                <xsl:with-param name="columnName" select="name()" />
              </xsl:call-template>
            </xsl:for-each>
          </tr>
          <xsl:for-each select="Developer">
            <xsl:call-template name="row">
            </xsl:call-template>           
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

<xsl:stylesheet version="1.0">
  <xsl:template name="header">
    <xsl:param name="columnName" select="'N/A'" />
    <th xmlns="http://www.w3.org/1999/xhtml">
      <xsl:value-of select="$columnName"/>
    </th>
  </xsl:template>
  <xsl:template name="row">
    <tr xmlns="http://www.w3.org/1999/xhtml">
      <td>
        <xsl:value-of select="Name"/>
      </td>
      <td>
        <ul>
          <xsl:for-each select="Skills/*">
            <li>
              <xsl:value-of select="text()"/>
            </li>
          </xsl:for-each>
        </ul>
      </td>
      <td>
        <xsl:for-each select="Address/*">
          <xsl:value-of select="text()"/>
          <br />
        </xsl:for-each>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

Sample output from above XSLT,

Developers

Name Skills Address
Jim
  • C#
  • MSSQL 2005
  • Web
Queen St
Auckland
Tom
  • Java
  • PostgreSql
  • XML, JSON
George St
Dunedin

Download the C# solution source code of this post




Posted in XML • Tags: , , Top Of Page

One Response to “XSLT XML transformation vs Object mapping”

Comment from janj
Time July 28, 2009 at 7:42 pm

chrome 2 javascript xml xslt support code.

Write a comment


Captcha: seven + 7 =