It is always fun to return to one of my favorite topics: errors and warnings, causes and solutions, especially when working with XSLT mappings.
When you develop or maintain XSLT maps—very common in BizTalk Server, Azure Logic Apps, and Azure Integration Services—you may suddenly encounter the following error during compilation or runtime:
Microsoft.XLANGs.Core.XTransformationFailureException: Error encountered while executing the transform mapD96A_INVOIC.
Error:Transformation failed.. —> System.Xml.Xsl.XslLoadException: ‘xsl:when’ cannot be a child of the ‘xsl:element’ element.
at System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object stylesheet, XsltSettings settings, XmlResolver stylesheetResolver)
at Microsoft.XLANGs.BaseTypes.CompiledXsltWrapperTransform.Load(String xslt)
at Microsoft.XLANGs.BaseTypes.TransformBase.get_Transform2()
at Microsoft.XLANGs.Core.Service.ApplyTransform(Type mapRef, TransformMetaData trfMetaData, Stream[] inStreams)
— End of inner exception stack trace —
at Microsoft.XLANGs.Core.Service.ApplyTransform(Type mapRef, TransformMetaData trfMetaData, Stream[] inStreams)
at Microsoft.XLANGs.Core.Service.ApplyTransform(Type mapRef, Object[] outParams, Object[] inParams)
or
Microsoft.XLANGs.Core.XTransformationFailureException: Error encountered while executing the transform mapD96A_INVOIC.
Error:Transformation failed.. —> System.Xml.Xsl.XslLoadException: ‘xsl:when’ cannot be a child of the ‘xsl:if’ element.
At first glance, this error may seem confusing, particularly when the XSLT appears syntactically correct. However, the root cause is usually simple and relates to an incorrect XSLT structure.
The good news is clear: this issue is not a product bug. Instead, it almost always comes from a misplaced conditional instruction in your XSLT.
📝 One-Minute Brief
When working with XSLT maps, the error ‘xsl:when’ cannot be a child of the ‘xsl:element’ element occurs because conditional logic is placed in an invalid location. In XSLT, xsl:when must always be inside an xsl:choose block and cannot be directly nested under xsl:element. This issue is common in BizTalk and Azure Integration Services mappings, especially when manually editing XSLT. The solution is simple: wrap your conditions inside xsl:choose and place it within the element you are generating. Once corrected, the map compiles and runs as expected.
Cause
To understand this error, we must remember one important XSLT rule:
- ✅
xsl:whencan only exist insidexsl:choose. - ❌ It cannot be directly nested inside
xsl:element. - ❌ It cannot be directly nested inside
xsl:if.
A common incorrect pattern looks like this:
<xsl:element name="Status">
<xsl:when test="Amount > 0">
<xsl:text>Approved</xsl:text>
</xsl:when>
</xsl:element>
This structure is an invalid XSLT. The xsl:element instruction is used to dynamically create elements, but it cannot directly contain conditional instructions like xsl:when.
When the XSLT processor encounters this, it throws an error complaining that xsl:when is not allowed as a child of xsl:element.
Solution
The fix is straightforward: wrap your conditional logic inside an xsl:choose block and place it inside the xsl:element.
The correct and valid XSLT example:
<xsl:element name="Status">
<xsl:choose>
<xsl:when test="Amount > 0">
<xsl:text>Approved</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Rejected</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
This structure follows the XSLT specification:
xsl:choosehandles conditional logicxsl:whenandxsl:otherwisedefine the conditionsxsl:elementonly contains valid child instructions
Once corrected, the mapping will be executed without errors.
Hope you find this helpful! If you liked the content or found it useful and would like to support me in writing more, consider buying (or helping to buy) a Star Wars Lego set for my son.