Adding an XSLT extension
Extend XSLT Functions with C# Code
If you want to execute some C# code from XSLT functions, you can create an XSLT extension object.
What you need to do is:
- Write a C# class that represents the extension
- Add information about the class to the
/App_Data/Composite/Composite.configfile - Add a namespace to your XSLT function
As an example, here's a class that has 2 methods:
- The first method gets a value from a HTTP posted form.
- The second one does HTML-encoding of a text and converts new line characters "\r\n" into
<br/>tags, so line breaks in text will be line breaks in XHTML.
Note that a class should be "public", not-static and should be marked with the necessary attribute, visible methods should be public and non-static.
using System;
using System.Net;
using System.Text;
using System.Web;
using System.Xml.Linq;
using System.Xml.XPath;
using Composite.Plugins.Functions.XslExtensionsProviders.ConfigBasedXslExtensionsProvider;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
namespace Composite.Examples
{
[ConfigurationElementType(typeof(ConfigBasedXslExtensionInfo))]
public class ExtensionObject
{
public string GetFormData(string key)
{
var httpContext = HttpContext.Current;
if (httpContext == null || httpContext.Request == null || httpContext.Request.Form == null)
{
return string.Empty;
}
return httpContext.Request.Form[key] ?? string.Empty;
}
public XPathNavigator ParseLineBreaks(string text)
{
string[] parts = text.Split(new string[] {Environment.NewLine}, StringSplitOptions.None);
StringBuilder html = new StringBuilder("<div>"); for (int i = 0; i < parts.Length; i++)
{
if (i > 0)
html.Append("<br />");
html.Append(WebUtility.HtmlEncode(parts[i]));
}
html.Append("</div>");
return XElement.Parse(html.ToString()).CreateNavigator();
}
}
}
These are the changes to be made in /App_Data/Composite/Composite.config:
<configuration>
<!-- skipped -->
<Composite.Functions.Plugins.XslExtensionsProviderConfiguration>
<XslExtensionProviders>
<add name="ConfigurationBasedXslExtensionsProvider"
type="Composite.StandardPlugins.Functions.XslExtensions.ConfigBasedXslExtensionsProvider">
<xslExtensions>
<!--- skipped -->
<add name="http://c1.composite.net/Example"
type="Composite.Examples.ExtensionObject, App_Code" />
</xslExtensions>
</add>
</XslExtensionProviders>
</Composite.Functions.Plugins.XslExtensionsProviderConfiguration>
</configuration>The XSLT function example:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" xmlns:e="http://c1.composite.net/Example" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xsl in">
<xsl:template match="/">
<!-- Using the extension method in order to check if current form was submitted -->
<xsl:variable name="formPosted" select="e:GetFormData('formId') = 'feedbackForm'" />
<html>
<head></head>
<body>
<xsl:choose>
<xsl:when test="not($formPosted)">
<form method="post">
<!-- Some markup here -->
<input type="hidden" name="formId" value="feedbackForm" />
<textarea name="textArea1" />
<br />
<input type="submit" />
</form>
</xsl:when>
<xsl:otherwise>
Thank you for the participation. <br /> The text you entered: <xsl:copy-of select="e:ParseLineBreaks(e:GetFormData('textArea1'))" />
</xsl:otherwise>
</xsl:choose>
</body>
</html>
</xsl:template>
</xsl:stylesheet>The highlights to the above example:
- We specify the namespace ("e") for our extension:
xmlns:e="http://c1.composite.net/Example" - We use our first extesion method
GetFormDatato check if the form has been submitted:<xsl:variable name="formPosted" select="e:GetFormData('formId') = 'feedbackForm'" /> - We use second method
ParseLineBreaks(on the output of the first method) to correctly present the data the user has entered in the form:<xsl:copy-of select="e:ParseLineBreaks(e:GetFormData('textArea1'))" />

