4

I'm using a system which consists of many complex XSL transforms which each work on large XML files. A proprietary program compiles the XSLT on each of the XML files, before passing the XML files to our databases.

The XSL transforms almost always involve C# functions within <msxsl> tags, many which are repeated between several files with the code copied manually. I'm trying to implement a system where a general repository of functions are stored in one file, and then loaded into the XSLT file before being read by the <msxsl> tags.

My problem is that I have been unable to find a way to have the code within <msxsl> loaded from an external file. Here's an example of what I mean:

The transform with the function hard-coded:

...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:msxsl="urn:schemas-microsoft-com:xslt"
            xmlns:cs="urn:my-scripts-csharp">

...

<msxsl:script language="C#" implements-prefix="cs">
  <![CDATA[
    public string emphasise(string input) {
      return input+"!";
    }
  ]]>
</msxsl:script>

...

Whilst I'd like the function loaded externally:

...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:msxsl="urn:schemas-microsoft-com:xslt"
            xmlns:cs="urn:my-scripts-csharp">
...

<msxsl:script language="C#" implements-prefix="cs">
  <--- file loaded here --->
</msxsl:script>

...

Where the source file would be something like:

<![CDATA[
  public string emphasise(string input) {
    return input+"!";
  }
]]>

Is this possible? The functions are generally complex (unlike this example) and cannot be reproduced with XSLT code. Would namespace and using keywords from the external file be read or would I have to include them outside of it with <msxsl:using> tags?

I'm quite new to the use of <msxsl> tags, and if I'm misunderstanding something fundamental then do please let me know!

2 Answers 2

3

I. Here is how to do it:

File: C:\temp\delete\c#script.xsl

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:cs="urn:my-scripts-csharp">  
    <msxsl:script language="C#" implements-prefix="cs">
    <![CDATA[
     public string emphasise(string input)
     {
      return input+"!";
      }
      ]]></msxsl:script>
</xsl:stylesheet>

Your transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:cs="urn:my-scripts-csharp">

 <xsl:include href="C:\temp\delete\c#script.xsl"/>

 <xsl:template match="/">
  <xsl:value-of select="cs:emphasise('Hello')"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is performed (on any XML document), the wanted result is produced:

Hello!

Warning: Using inline scripts like these is known to cause memory fragmentation if the transformation is repeated many times and this can lead to memory leaks.

I strongly recommend not to use inline scripts at all. A better, more efficient and safe approach is to have all necessary extension functions in an extension object -- read about the XsltArgumentList class and its AddExtensionObject() method.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks very much. I have looked into XsltArgumentList but for the time being I don't have access to the source code that reads the transforms.
2

You can reference code in external assemblies using : http://msdn.microsoft.com/en-us/library/ms256188.aspx - that could provide a way of moving your code to an external location

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.