SAP XSLT Mapping
XSLT stands for eXtensible Stylesheet Language Transformations. It is a language specifically designed to transform XML documents from one structure to another. Where the graphical message mapping editor works well for field-by-field transformations, XSLT excels at structural transformations — reorganizing the hierarchy of an XML document, grouping elements, sorting records, and generating calculated output that depends on the entire document rather than individual field values.
Think of XSLT like a stencil for XML. The stencil defines the shape of the output. You lay the stencil over the input XML, and the XSLT processor traces the stencil, filling in values from the input document wherever the stencil specifies. The resulting output matches the stencil's shape exactly, populated with data from the source.
The XSLT Step in CPI
CPI provides a dedicated XSLT Mapping step. You create an XSLT stylesheet file (.xsl or .xslt) and upload it as a resource in your integration package. The XSLT step references this file. At runtime, CPI applies the stylesheet to the message body and replaces the body with the transformed output.
XSLT Basics
An XSLT stylesheet is an XML document itself. It has a root element of xsl:stylesheet and contains templates that define how to handle different input elements:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Template matches the root of the source XML -->
<xsl:template match="/">
<SAPOrder>
<!-- Output the transformed structure here -->
<OrderNumber>
<xsl:value-of select="/PurchaseOrder/OrderID"/>
</OrderNumber>
<Vendor>
<xsl:value-of select="/PurchaseOrder/SupplierCode"/>
</Vendor>
</SAPOrder>
</xsl:template>
</xsl:stylesheet>
The xsl:template match="/" activates when the XSLT processor starts at the root of the document. Inside it, you write the output XML structure literally. Where you need values from the source, use xsl:value-of select="XPath expression".
Transforming Repeating Elements
XSLT handles loops through xsl:for-each. For every matching element in the source, it outputs one occurrence in the target:
Source XML:
<PurchaseOrder>
<OrderID>PO-001</OrderID>
<Items>
<Item><SKU>A100</SKU><Qty>50</Qty></Item>
<Item><SKU>B200</SKU><Qty>30</Qty></Item>
</Items>
</PurchaseOrder>
XSLT Stylesheet:
<xsl:template match="/">
<ORDERS05>
<E1EDK01>
<BELNR><xsl:value-of select="/PurchaseOrder/OrderID"/></BELNR>
</E1EDK01>
<xsl:for-each select="/PurchaseOrder/Items/Item">
<E1EDP01>
<MATNR><xsl:value-of select="SKU"/></MATNR>
<MENGE><xsl:value-of select="Qty"/></MENGE>
</E1EDP01>
</xsl:for-each>
</ORDERS05>
</xsl:template>
Output XML:
<ORDERS05>
<E1EDK01><BELNR>PO-001</BELNR></E1EDK01>
<E1EDP01><MATNR>A100</MATNR><MENGE>50</MENGE></E1EDP01>
<E1EDP01><MATNR>B200</MATNR><MENGE>30</MENGE></E1EDP01>
</ORDERS05>
Conditional Output in XSLT
Use xsl:if to output an element only when a condition is true, and xsl:choose for if-else-if logic:
<!-- Output RUSH flag only for urgent orders -->
<xsl:if test="/Order/Priority = 'URGENT'">
<RUSH_FLAG>X</RUSH_FLAG>
</xsl:if>
<!-- Map order type codes -->
<xsl:choose>
<xsl:when test="/Order/Type = 'STANDARD'">
<AUART>OR</AUART>
</xsl:when>
<xsl:when test="/Order/Type = 'RUSH'">
<AUART>RA</AUART>
</xsl:when>
<xsl:otherwise>
<AUART>OR</AUART>
</xsl:otherwise>
</xsl:choose>
XSLT Built-In Functions
XSLT 1.0 (the version CPI supports by default) includes useful built-in functions:
string-length(text)– Returns the length of a stringsubstring(text, start, length)– Extracts part of a stringconcat(a, b, c)– Concatenates stringstranslate(text, from, to)– Replaces charactersnormalize-space(text)– Trims whitespacenumber(text)– Converts string to numbercount(nodeset)– Counts elementssum(nodeset)– Sums numeric values across elementsformat-number(value, pattern)– Formats numbers with decimal places
Passing Parameters into XSLT
CPI supports passing exchange properties as parameters into XSLT stylesheets. Define a parameter at the top of your stylesheet and CPI populates it at runtime:
In XSLT Stylesheet:
<xsl:param name="ProcessingDate"/>
<xsl:param name="CompanyCode"/>
<xsl:template match="/">
<Output>
<PostingDate><xsl:value-of select="$ProcessingDate"/></PostingDate>
<BUKRS><xsl:value-of select="$CompanyCode"/></BUKRS>
</Output>
</xsl:template>
In XSLT Step configuration:
Parameter Name: ProcessingDate
Data Type: String
Value: ${property.TodayDate}
Parameter Name: CompanyCode
Data Type: String
Value: ${property.CompanyCode}
When to Use XSLT vs Graphical Mapping
USE GRAPHICAL MESSAGE MAPPING WHEN: - Field-to-field mapping with function transformations - Repeating structure mapping (loops) - Most standard business document transformations - Team has mixed technical backgrounds USE XSLT WHEN: - Complex structural reorganization (sorting, grouping, merging nodes) - Conditional element generation based on multiple field values - Generating calculated summary elements (totals, subtotals) - Output format depends on the number or content of input nodes - Performance is critical (XSLT can be faster for large documents) - Team has strong XSLT/XML skills
Testing XSLT Stylesheets
Test XSLT stylesheets outside CPI first using free tools like Oxygen XML Editor, Altova XMLSpy, or even online XSLT testers. Paste your stylesheet and a sample input XML, run the transformation, and verify the output. Once the stylesheet produces correct output in the test tool, upload it to CPI and test again using CPI's simulation mode. This two-stage approach catches stylesheet logic errors before they reach the iFlow runtime.
