Showing posts with label Use code behind function in XSLT.. Show all posts
Showing posts with label Use code behind function in XSLT.. Show all posts

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>

*/