Adding an XSLT extension
EXPERIENCE MANAGEMENT > FUNCTIONS
If you want to execute some C# code from XSLT functions, you can create an XSLT extension object.
What you need to do is:
|
1.
|
Write a C# class that represents the extension |
|
2.
|
Add information about the class to the /App_Data/Composite/Composite.config file |
|
3.
|
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: A class should be public 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:
|
1.
|
We specify the namespace ("e") for our extension: xmlns:e="http://c1.composite.net/Example" |
|
2.
|
We use our first extesion method GetFormData to check if the form has been submitted: <xsl:variable name="formPosted" select="e:GetFormData('formId') = 'feedbackForm'" /> |
|
3.
|
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'))" /> |