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,