Monday, August 10, 2009

How to use external function in XSLT

Following is the Example of How to Call a code behind function from XSLT file.

Step 1. Create a class which contains the public methods which you want to Call in xslt file
For example

//THis has to be a public class.
Public class XsltExtension
{
//This method has to be Public - Because you are using it in the XSLT.
public string myCustomFunc(string inputFromXML)
{
return "***"+inputFromXML+"***";
}
}


Step 2. Now I would write my XSLT, where I have to provid the Namespace of the external functions to be used.
Suppose following is my xslt file

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:func="urn:actl-xslt">
<xsl:template match="root">
<root>
<xsl:for-each select="child">
<transformedChild>

<xsl:for-each select="somevalue">
<transformedChild>
<originalValue>
<xsl:value-of select="."/>
</originalValue>
<manipulatedValue>
<xsl:value-of select="func:myCustomFunc(.)"/>
</manipulatedValue>
</transformedChild>
</xsl:for-each>
</transformedChild>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>

Please note the attribute that I have added here as - xmlns:func="urn:actl-xslt"
and the prefix added to my external method as func:myCustomFunc(.)

Step 3. Now I will write a method where I will attach above class(in step 1) to my XSLT. So that XSLT comes to know
of which class's methods it has to use.


//Suppose this is My XML

string SampleXml = @"<root>" +
"<child>" +
"<somevalue>cow</somevalue>" +
"</child>" +
"<child>" +
"<somevalue>sheep</somevalue>" +
"</child>" +
"</root>";

XmlDocument xDoc1 = new XmlDocument();
xDoc1.LoadXml(SampleXml);

XmlElement input = xDoc1.DocumentElement;
XsltArgumentList xsltArguments=null;
XsltExtension xsltExtension = new XsltExtension();

string xsltFile = Server.MapPath("DoTransform.xsl");


xsltArguments = new XsltArgumentList();
xsltArguments.AddExtensionObject("urn:actl-xslt", xsltExtension);

//Create string writer to store resultant transformed XML
StringWriter result = new StringWriter();
//Generate XML document outof xml element
XPathDocument xDoc = new XPathDocument(new StringReader(input.OuterXml));
//Create transformation class
XslCompiledTransform xslt = new XslCompiledTransform(true);

XsltSettings xsltSettings = new XsltSettings();
xsltSettings.EnableScript = true;
xslt.Load(xsltFile, xsltSettings, new XmlUrlResolver());
//perform transformation
xslt.Transform(xDoc, xsltArguments, result);
//generate XML element
XmlDocument resultDoc = new XmlDocument();
resultDoc.LoadXml(result.ToString());


/*
In the above code you can see that I have used xsltArguments where I have given the exaclt same namespace
as i have given in my xslt's attribute - urn:actl-xslt

Now when you will see the output of the above xml it would look like this.


<?xml version="1.0" encoding="utf-16"?>
<root xmlns:func="urn:actl-xslt">
<transformedChild>
<transformedChild>
<originalValue>cow</originalValue>
<manipulatedValue>***cow***</manipulatedValue>
</transformedChild>
</transformedChild>
<transformedChild>
<transformedChild>
<originalValue>sheep</originalValue>
<manipulatedValue>***sheep***</manipulatedValue>
</transformedChild>
</transformedChild>
</root>

*/

No comments:

Post a Comment