Skip to content
LambogeniusDocs

Compose using XSLT for Azure Logic Apps

C# scripts

msxsl:script C# helpers: what is supported, how they are compiled, and how errors point at the map.

Service provider/serviceProviders/lamboXsltComposeOperation ComposeXslt, shown in the designer as Compose using XSLT.

Embedded C# in msxsl:script

Set enableScripts to true. Script blocks are compiled with Roslyn when the map is first used, then cached per worker.

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:fmt="urn:samples:format"
    exclude-result-prefixes="msxsl fmt">

  <msxsl:script language="C#" implements-prefix="fmt">
    <![CDATA[
      private static readonly System.Globalization.CultureInfo Invariant = System.Globalization.CultureInfo.InvariantCulture;

      public string Money(double amount, string currency)
      {
          return amount.ToString("#,##0.00", Invariant) + " " + currency;
      }

      public string PostalCode(string value)
      {
          var code = Regex.Replace(value ?? "", "[^A-Za-z0-9]", "").ToUpperInvariant();
          return code.Length == 6 ? code.Substring(0, 3) + " " + code.Substring(3) : code;
      }
    ]]>
  </msxsl:script>

  <xsl:template match="/Order">
    <Total><xsl:value-of select="fmt:Money(sum(Lines/Line/Amount), 'CAD')"/></Total>
    <PostalCode><xsl:value-of select="fmt:PostalCode(string(ShipTo/PostalCode))"/></PostalCode>
  </xsl:template>
</xsl:stylesheet>

What is supported

  • Public instance methods with string, bool and double parameters and return values (XPath string, boolean, number).
  • Private helpers, instance fields, and static readonly or const fields. A fresh instance per transformation, so state never leaks between runs.
  • Namespaces: System, System.Text and System.Text.RegularExpressions are in scope; write other framework types with their full names (System.Globalization.CultureInfo).
  • Several blocks. Binding is by namespace URI: blocks with the same URI form one class, under any prefix; scripts in imported modules work too.
  • C# only (C# 12 syntax). VB and JScript blocks, msxsl:assembly, and out-of-subset features are rejected with UnsupportedScriptFeature, naming the line and rule.

Errors point at the map

Compile errors carry the original map line: ScriptCompilationFailed: … errors/script-syntax-error.xslt(9,30): CS1002 ; expected. Exceptions thrown by a script give ScriptExecutionFailed with the method name and exception type, never the data.

A stuck script is stopped

Scripts run in a worker process. A loop that never returns is stopped at the action's timeoutSeconds with TransformationTimeout; the worker is killed and replaced, and the next run works normally.

Operators can turn scripts off for the whole app with XsltCompose__AllowScripts=false (ScriptsDisabled).