Azure Logic Apps — XSLT Transforms

Enterprise XML Data Transformation with Maps


What Are XSLT Transforms?

XSLT (Extensible Stylesheet Language Transformations) is a declarative language for transforming XML documents into other XML documents, HTML, or plain text. In enterprise integration, XSLT serves as the backbone for converting data between disparate systems that speak different XML dialects.

Why XSLT Matters in Enterprise Integration

  • B2B/EDI Processing — Trading partners exchange documents (purchase orders, invoices, shipping notices) in formats like EDIFACT and X12. XSLT maps convert these into internal canonical formats.
  • Legacy System Integration — Older ERP and mainframe systems often produce proprietary XML schemas. XSLT bridges the gap between legacy output and modern API expectations.
  • Healthcare (HL7/FHIR) — Clinical data exchange requires precise structural transformations between HL7v2 XML, CDA documents, and FHIR resources.
  • SAP Integration — SAP IDocs and BAPIs expose XML interfaces that rarely match downstream system schemas directly.
  • Data Normalization — When multiple sources feed into a single system, XSLT standardizes varying structures into a unified canonical model.

How Logic Apps Handles XML Transformations

Azure Logic Apps provides the Transform XML action for XSLT-based transformations. The architecture involves:

  1. Integration Account — A separate Azure resource that stores XSLT maps, schemas, and certificates.
  2. Map Artifacts — XSLT files uploaded to the Integration Account, referenced by name in workflows.
  3. Transform XML Action — A built-in action that takes XML input, applies a named map, and outputs the transformed result.

Logic Apps links to an Integration Account at the workflow level. Once linked, all maps stored in that account become available to Transform XML actions within the workflow.

Supported Map Types

Map TypeUse Case
XSLT 1.0Standard XML-to-XML transforms (default)
XSLT 2.0Advanced transforms with grouping, regex, multiple outputs
XSLT 3.0Streaming, JSON output, maps (Standard plan only)
LiquidJSON-to-JSON or JSON-to-text transforms

Creating XSLT Maps

Using Visual Studio with BizTalk Server Tools

The BizTalk Server extension for Visual Studio provides a graphical mapper for creating XSLT maps:

  1. Create a BizTalk Server project in Visual Studio.
  2. Add source and destination schemas (.xsd files).
  3. Add a new Map (.btm) file.
  4. Drag connections between source and destination fields.
  5. Use functoids for string manipulation, math, and conditional logic.
  6. Test the map and export the generated XSLT.

Using VS Code

For hand-crafted XSLT, VS Code with the XML extension provides:

  • Syntax highlighting and IntelliSense for XSLT
  • Schema validation
  • Snippet support for common XSLT patterns

Sample XSLT Map — Order Transformation

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns0="http://schemas.example.com/source/order"
    xmlns:ns1="http://schemas.example.com/canonical/order"
    exclude-result-prefixes="ns0">

    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

    <xsl:template match="/ns0:PurchaseOrder">
        <ns1:CanonicalOrder>
            <ns1:Header>
                <ns1:OrderId><xsl:value-of select="ns0:OrderID"/></ns1:OrderId>
                <ns1:OrderDate><xsl:value-of select="ns0:Date"/></ns1:OrderDate>
                <ns1:Currency><xsl:value-of select="ns0:Currency"/></ns1:Currency>
            </ns1:Header>
            <ns1:Customer>
                <ns1:Name><xsl:value-of select="ns0:BuyerInfo/ns0:Name"/></ns1:Name>
                <ns1:AccountId><xsl:value-of select="ns0:BuyerInfo/ns0:AccountNumber"/></ns1:AccountId>
            </ns1:Customer>
            <ns1:LineItems>
                <xsl:for-each select="ns0:Items/ns0:Item">
                    <ns1:LineItem>
                        <ns1:SKU><xsl:value-of select="ns0:ProductCode"/></ns1:SKU>
                        <ns1:Quantity><xsl:value-of select="ns0:Qty"/></ns1:Quantity>
                        <ns1:UnitPrice><xsl:value-of select="ns0:Price"/></ns1:UnitPrice>
                        <ns1:Total><xsl:value-of select="ns0:Qty * ns0:Price"/></ns1:Total>
                    </ns1:LineItem>
                </xsl:for-each>
            </ns1:LineItems>
        </ns1:CanonicalOrder>
    </xsl:template>
</xsl:stylesheet>

Uploading Maps to Integration Account

Via Azure CLI

# Create the Integration Account (if not exists)
az logic integration-account create \
  --name my-integration-account \
  --resource-group my-rg \
  --location eastus \
  --sku Standard

# Upload an XSLT map
az logic integration-account map create \
  --integration-account-name my-integration-account \
  --resource-group my-rg \
  --name OrderTransform \
  --map-type Xslt \
  --content-type application/xml \
  --map-content @./maps/order-transform.xslt

Via Azure Portal

  1. Navigate to your Integration Account resource.
  2. Select Maps under Settings.
  3. Click Add, provide a name, select map type (XSLT, XSLT 2.0, or XSLT 3.0).
  4. Upload the .xslt file.
  5. Click OK to save.

Using the Transform XML Action in Logic Apps

Consumption Plan (Logic App Designer)

  1. Link your Logic App to an Integration Account (Logic App → Workflow settings → Integration Account).
  2. Add the Transform XML action to your workflow.
  3. Set the Content to the XML payload (e.g., trigger body or a previous action output).
  4. Select the Map Name from the dropdown (populated from Integration Account).

Workflow JSON Definition

{
  "actions": {
    "Transform_XML": {
      "type": "Xslt",
      "kind": "Xslt",
      "inputs": {
        "content": "@triggerBody()",
        "integrationAccount": {
          "map": {
            "name": "OrderTransform"
          }
        }
      },
      "runAfter": {}
    },
    "Send_Transformed_Output": {
      "type": "Http",
      "inputs": {
        "method": "POST",
        "uri": "https://api.internal.example.com/orders",
        "headers": {
          "Content-Type": "application/xml"
        },
        "body": "@body('Transform_XML')"
      },
      "runAfter": {
        "Transform_XML": ["Succeeded"]
      }
    }
  }
}

Handling Namespaces and Complex Mappings

Namespaces are the most common source of XSLT failures in enterprise integration. Key rules:

Declare All Namespaces

Every namespace in the source XML must be declared in the xsl:stylesheet element:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:sap="urn:sap-com:document:sap:rfc:functions"
    xmlns:edi="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
    exclude-result-prefixes="sap edi">

Use exclude-result-prefixes

Prevents source namespaces from leaking into the output document.

Conditional Logic for Complex Mappings

<xsl:template match="ns0:LineItem">
    <OutputItem>
        <xsl:choose>
            <xsl:when test="ns0:Type = 'PHYSICAL'">
                <Category>Goods</Category>
            </xsl:when>
            <xsl:when test="ns0:Type = 'SERVICE'">
                <Category>Services</Category>
            </xsl:when>
            <xsl:otherwise>
                <Category>Other</Category>
            </xsl:otherwise>
        </xsl:choose>
        <Description><xsl:value-of select="normalize-space(ns0:Desc)"/></Description>
    </OutputItem>
</xsl:template>

XSLT 1.0 vs 2.0 Support in Logic Apps

FeatureXSLT 1.0XSLT 2.0
AvailabilityConsumption + StandardConsumption + Standard
Grouping (for-each-group)Not supportedSupported
Regular expressionsNot supportedSupported (matches(), replace())
Multiple output documentsNot supportedSupported
Date/time functionsNot supportedSupported
Map type in Integration AccountXsltXslt20

Recommendation: Use XSLT 1.0 for simple field mappings. Use XSLT 2.0 when you need grouping, regex, or date manipulation. XSLT 3.0 is available on the Standard plan and adds JSON serialization and streaming for large documents.


Real-World Scenarios

EDI X12 850 to Canonical JSON

A common B2B pattern: receive an EDI 850 Purchase Order, decode it, transform the resulting XML to a JSON canonical model, then post to an internal API.

Flow: AS2 Receive → Decode X12 → Transform XML (XSLT) → Compose JSON → HTTP POST

SAP IDoc Integration

SAP sends IDocs (e.g., ORDERS05) as XML via RFC or file drop. XSLT maps the IDoc structure (with deep nesting and SAP-specific segments like E1EDK01, E1EDP01) into a flat canonical order format.

Healthcare HL7 to FHIR

HL7v2 messages converted to XML (via HL7 decode) are transformed using XSLT into FHIR Bundle resources for submission to a FHIR server.


Testing Transforms

Local Testing

Test XSLT maps locally before uploading:

# Using xsltproc (macOS/Linux)
xsltproc maps/order-transform.xslt test-data/sample-order.xml

# Using Saxon for XSLT 2.0/3.0
java -jar saxon-he.jar -s:test-data/sample-order.xml -xsl:maps/order-transform.xslt

Testing in Azure Portal

  1. Open the map in your Integration Account.
  2. Click Test in the toolbar.
  3. Paste or upload sample XML input.
  4. Review the transformed output and verify correctness.

Automated Testing in CI/CD

Include transform tests in your pipeline:

# Azure DevOps pipeline step
- script: |
    xsltproc maps/order-transform.xslt tests/input.xml > tests/actual-output.xml
    diff tests/expected-output.xml tests/actual-output.xml
  displayName: 'Validate XSLT Transform'

Best Practices

  1. Version your maps — Store XSLT files in source control alongside schemas. Use naming conventions like OrderTransform_v2.xslt.
  2. Use a canonical model — Map all external formats to/from a single internal canonical schema rather than point-to-point transforms.
  3. Keep maps simple — Break complex transformations into multiple steps rather than one monolithic XSLT.
  4. Validate input first — Use the XML Validation action with an XSD schema before applying transforms to catch malformed input early.
  5. Handle missing elements gracefully — Use xsl:if or default values to avoid empty output nodes when optional source fields are absent.
  6. Test with edge cases — Empty collections, special characters, maximum field lengths, and Unicode content.
  7. Monitor transform failures — Set up alerts on the Transform XML action failure rate in Azure Monitor.

Common Pitfalls

PitfallSolution
Namespace mismatch — transform produces empty outputEnsure all source namespaces are declared in the stylesheet
Large XML (>10 MB) causes timeoutUse chunking or switch to Standard plan with XSLT 3.0 streaming
Map not found at runtimeVerify Integration Account is linked and map name matches exactly (case-sensitive)
Output encoding issuesExplicitly set <xsl:output encoding="UTF-8"/>
Whitespace in outputUse <xsl:strip-space elements="*"/> to remove unwanted whitespace
XSLT 2.0 functions failEnsure map type is set to Xslt20 in Integration Account, not Xslt

Summary

XSLT transforms in Azure Logic Apps provide a robust, standards-based approach to XML data transformation for enterprise integration. Combined with Integration Accounts for artifact management and the Transform XML action for execution, they enable complex B2B, EDI, and legacy system integrations without custom code.


Azure Integration Hub — Advanced Level