web analytics

How to embed C# functions in a XSLT style sheet?

Options

codeling 1599 - 6654
@2015-12-24 15:55:18

The XslCompiledTransform class supports embedded scripts using the msxsl:script element in a XSLT style sheet. When the style sheet is loaded, any defined functions are compiled to Microsoft intermediate language (MSIL) by the Code Document Object Model (CodeDOM) and are executed during run time. The assembly generated from the embedded script block is separate than the assembly generated for the style sheet.

By default, script support is disabled in the XslCompiledTransform class. To enable script support, create an XsltSettings object with the EnableScript property set to true and pass the object to the Load method.

msxsl:script Element

The msxsl:script element is a Microsoft extension to the XSLT 1.0 recommendation and has the following definition:

<msxsl:script language = "language-name" implements-prefix = "prefix of user namespace"> </msxsl:script>

The msxsl prefix is bound to the urn:schemas-microsoft-com:xslt namespace URI. The style sheet must include the xmlns:msxsl=urn:schemas-microsoft-com:xslt namespace declaration.

The language attribute is optional. Its value is the code language of the embedded code block.

The implements-prefix attribute is mandatory. This attribute is used to declare a namespace and associate it with the script block. The value of this attribute is the prefix that represents the namespace. This prefix can be defined somewhere in a style sheet.

<msxsl:script implements-prefix='your-prefix' language='C#'>
< ![CDATA[
// Code block.
]]>
< /msxsl:script>

Importing Namespaces and Assemblies

The XslCompiledTransform class predefines a set of assemblies and namespaces that are supported by default by the msxsl:script element. However, you can use classes and members belonging to a namespace that is not on the predefined list by importing the assembly and namespace in msxsl:script block.

The following two assemblies are referenced by default:

  • System.dll
  • System.Xml.dll
  • Microsoft.VisualBasic.dll (when the script language is VB)

You can import the additional assemblies using the msxsl:assembly element. This includes the assembly when the style sheet is compiled. The msxsl:assembly element has the following definition:

<msxsl:script>
  <msxsl:assembly name="system.assemblyName" />
  <msxsl:assembly href="path-name" />
    <![CDATA[
    // User code
    ]]>
< /msxsl:script>

The name attribute contains the name of the assembly and the href attribute contains the path to the assembly.

The following namespaces are included by default:

  • System
  • System.Collection
  • System.Text
  • System.Text.RegularExpressions
  • System.Xml
  • System.Xml.Xsl
  • System.Xml.XPath
  • Microsoft.VisualBasic (when the script language is VB)

You can add support for additional namespaces using the namespace attribute. The attribute value is the name of the namespace.

<msxsl:script>
  <msxsl:using namespace="system.namespaceName" />
    <![CDATA[
    // User code
    ]]>
< /msxsl:script>

Example

The following example uses an embedded script to calculate the circumference of a circle given its radius.

using System;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;

public class Sample {

  private const String filename = "number.xml";
  private const String stylesheet = "calc.xsl";

  public static void Main() {

    // Compile the style sheet.
    XsltSettings xslt_settings = new XsltSettings();
    xslt_settings.EnableScript = true;
    XslCompiledTransform xslt = new XslCompiledTransform();
    xslt.Load(stylesheet, xslt_settings, new XmlUrlResolver());

    // Load the XML source file.
    XPathDocument doc = new XPathDocument(filename);

    // Create an XmlWriter.
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.OmitXmlDeclaration = true;
    settings.Indent = true;
    XmlWriter writer = XmlWriter.Create("output.xml", settings);

    // Execute the transformation.
    xslt.Transform(doc, writer);
    writer.Close();
  }
}

number.xml

<?xml version='1.0'?>
< data>
  <circle>
    <radius>12</radius>
  </circle>
  <circle>
    <radius>37.5</radius>
  </circle>
< /data>

calc.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:user="urn:my-scripts">
  <msxsl:script language="C#" implements-prefix="user">
  <![CDATA[
  public double circumference(double radius){
    double pi = 3.14;
    double circ = pi*radius*2;
    return circ;
  }
  ]]>
  </msxsl:script>
  <xsl:template match="data">
    <circles>
      <xsl:for-each select="circle">
        <circle>
          <xsl:copy-of select="node()"/>
          <circumference>
            <xsl:value-of select="user:circumference(radius)"/>
          </circumference>
        </circle>
      </xsl:for-each>
    </circles>
  </xsl:template>
< /xsl:stylesheet>

Output

<circles xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:my-scripts">
  <circle>
    <radius>12</radius>
    <circumference>75.36</circumference>
  </circle>
  <circle>
    <radius>37.5</radius>
    <circumference>235.5</circumference>
  </circle>
< /circles>

Comments

You must Sign In to comment on this topic.


© 2024 Digcode.com