Note: This answer is taken from the top-level comments on this question and this github repo (which is linked in the comments). I just pulled everything together in an answer to make it easier for future readers.
You can use extension objects to call your own C# methods from XSLT.
For example, define the methods you want to use:
public class XsltFunctions
{
public static string ToLower(XPathNodeIterator iterator)
{
return iterator.OfType<XPathNavigator>().FirstOrDefault()?.Value.ToLower();
}
}
Then register that class as an extensions object when running your XSLT. (Pay attention to the AddExtensionObject method.)
public string RunXslt(string inputXml)
{
// xml transform pointing to custom code
var xsltDocumentString = $@"<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" xmlns:msxsl=""urn:schemas-microsoft-com:xslt"" xmlns:user=""{nameof(XsltFunctions)}"">
<xsl:template match=""MyElt"">
<MyElt>
<OriginalValue>
<xsl:copy-of select=""node()""/>
</OriginalValue>
<ToLowerValue>
<xsl:value-of select=""user:ToLower(node())""/>
</ToLowerValue>
</MyElt>
</xsl:template>
</xsl:stylesheet>";
// Compile the style sheet.
var xslt_settings = new XsltSettings();
var xslt = new XslCompiledTransform();
var styleSheetReader = new XmlTextReader(new StringReader(xsltDocumentString));
xslt.Load(styleSheetReader, xslt_settings, new XmlUrlResolver());
// Add capability to ref external functions
var xsltArgList = new XsltArgumentList();
xsltArgList.AddExtensionObject(nameof(XsltFunctions), new XsltFunctions());
// Load the XML source file.
XmlReader inputDataReader = new XmlTextReader(new StringReader(inputXml));
// Create an XmlWriter.
var settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Indent = true;
var output = new StringBuilder();
var writer = new XmlTextWriter(new StringWriter(output));
// Execute the transformation.
xslt.Transform(inputDataReader, xsltArgList, writer);
// return the transformed XML response to the caller
return output.ToString();
}
Tested in .NET Core 2.1 and .NET 5, using the following NUnit test.
[Test]
public void RunXsltWithExternalFunctions()
{
// Arrange.
var inputXml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<MyXml>
<MyElt>
MyEltValue
</MyElt>
</MyXml>";
// Act.
var outputXml = RunXslt(inputXml);
// Assert.
Assert.That(outputXml, Does.Contain("myeltvalue"));
}
Source
See also: XSLT Extension Objects
ms:scriptinside the XSLT but you should be able to use extension objects to call any .NET framework function as done in github.com/brandonh-msft/EmbeddedXsltTestFunction/blob/master/…. So you would need to move any VB code out of the XSLT and implement/wrap it as an extension object you pass with an XsltArgumentList to theTransformmethod. And it is JScript.NET or C# or VB.NET support you get, not VBScript.$sign with the string literal containing the XSLT code? That means in the linked example the{nameof(XSLTFunctions)}is evaluated and the final XSLT is computed in the C# code.xmlns:mf="http://example.com/mf"in the XSLT and thenmf:foo()to call a function in that namespace andxsltArgList.AddExtensionObject("http://example.com/mf", yourCSharpObjectOrClass).