Using .NET methods in your XSLT

Not many people know that it is possible to use a .NET object as an extension object when transforming XML with XSLT. Imagine that you want to recalculate the price of a book and round the result number. Impossible to calculate within XSLT, since it’s a transformation language and not a programming language.

Solution is to create a class with a method that performs the calculation. Then when transforming add this opject as an extension object to the XsltArgumentList.

The C# code:

 

    public class BookPrice
    {
        public decimal NewPrice(decimal price, decimal conv)
        {
            return decimal.Round(price * conv, 2);
        }
    }
 
     private void btnTransExten_Click(object sender, EventArgs e)
        {
            XslCompiledTransform trans = new XslCompiledTransform();
            trans.Load(@"..\..\prices.xslt");
 
            XsltArgumentList args = new XsltArgumentList();
 
            BookPrice price = new BookPrice();
            args.AddExtensionObject("urn:price-conv", price);
 
            trans.Transform(@"..\..\books.xml", args, XmlWriter.Create(@"c:\outputext.xml"));
           
            MessageBox.Show("File transformed.");
 
        }

 

The XSLT will look something like this:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:myObj="urn:price-conv">
  <xsl:param name="conv" select="1.15"/>
  <xsl:template match="booklist">
    <booklist>
      <xsl:for-each select="book">
        <book>
          <xsl:copy-of select="node()"/>
          <new-price>
            <xsl:value-of select="myObj:NewPrice(./price, $conv)"/>
          </new-price>
        </book>
      </xsl:for-each>
    </booklist>
  </xsl:template>
</xsl:stylesheet>

 

Hope this helps,