Back again to one of my favorite topics: transformations. This is something that several people asked me for help with in the past, but I never found time to reply… until now.
A quick note: if you want to learn more about BizTalk Maps transformations, check out my free book on the BizTalk360 website: BizTalk Mapping Patterns & Best Practices.
📝 One-Minute Brief
Solve BizTalk map error “ns1 is an undeclared prefix” in inline XSLT scripts. Use xsl:element or declare xmlns:ns1 locally.
While migrating an older BizTalk Map transformation, from a custom schema to a SAP IDOC schema, from an entire custom XSLT file to BizTalk Mapper (don’t get me wrong, I only made this migration because the source schema changed so I had the need to change the entire XSLT code, otherwise I would have used the existing external file), I had the need to implement some part of the transformation in an Inline XSLT code (using a Scripting Functoid) and I only used inline XSLT because I was transforming a flat structure from the source schema to a recursive node in the target schema base on some conditions (otherwise I would have used the Table Lopping Functoid)

<ns1:E2EDKA1003>
<ns1:DATAHEADERCOLUMN_SEGNAM>E2EDKA1003</ns1:DATAHEADERCOLUMN_SEGNAM>
<ns1:PARVW>LF</ns1:PARVW>
<ns1:PARTN>0000100000</ns1:PARTN>
</ns1:E2EDKA1003>
<ns1:E2EDKA1003>
<ns1:DATAHEADERCOLUMN_SEGNAM>E2EDKA1003</ns1:DATAHEADERCOLUMN_SEGNAM>
<ns1:PARVW>ZC</ns1:PARVW>
<ns1:PARTN>
<xsl:choose>
<xsl:when test="@Transportation='1'">
<xsl:value-of select="'0000100001'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'0000100009'" />
</xsl:otherwise>
</xsl:choose>
</ns1:PARTN>
</ns1:E2EDKA1003>
Note that I’m using the prefix “ns1” on the element because the schemas are expecting that, and it should work because both the schema and the transformation file (XSL) contain the namespace:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
…
xmlns:s1="http://unicer.pt/OrderUnigest01.xsd"
xmlns:ns1="http://Microsoft.LobServices.Sap/2007/03/Types/Idoc/3/ORDERS01//700"
xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp">

You can validate that by:
- Right-click on the map and select the Validate Map option.
- On the Output windows, click on the link present in the option The output XSLT is stored in the following file: file:///C:\Users\user\AppData\Local\Temp\2\_MapData\name.xsl.
However, when you either compile the map or validate it, we get the following error message:
Validate the map or compile it, and I get the following error:
Exception Caught: ‘ns1’ is an undeclared prefix. Line …, position …
Cause
Well, unfortunately, BizTalk Mapper Editor doesn’t like prefixes in inline XSLT code. Although they exist, it is not able to understand them without additional information in the code, which makes our work a little more difficult, or we need to use a different strategy in our XSLT code.
Luckily, we can easily fix this strange behavior of the editor.
Solution
The cleanest way to solve this strange behavior is to use the <xsl:element> element or <xsl:attribute> element to create the records, elements, and attributes required, instead of manually creating them <ns1:E2EDKA1003></ns1:E2EDKA1003> without the <xsl:element> element:
<xsl:element name="ns1:E2EDKA1003">
<xsl:element name="ns1:DATAHEADERCOLUMN_SEGNAM">E2EDKA1003</xsl:element>
<xsl:element name="ns1:PARVW">LF</xsl:element>
<xsl:element name="ns1:PARTN">0000100000</xsl:element>
</xsl:element>
<xsl:element name="ns1:E2EDKA1003">
<xsl:element name="ns1:DATAHEADERCOLUMN_SEGNAM">E2EDKA1003</xsl:element>
<xsl:element name="ns1:PARVW">ZC</xsl:element>
<xsl:element name="ns1:PARTN">
<xsl:choose>
<xsl:when test="@Transportation='1'">
<xsl:value-of select="'0000100001'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'0000100009'" />
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:element>
If you don’t want to use the <xsl:element> element or <xsl:attribute> element, then you need to declare the prefix namespace in the record:
<xsl:element name="ns1:E2EDKA1003">
<ns1:E2EDKA1003 xmlns:ns1="http://Microsoft.LobServices.Sap/2007/03/Types/Idoc/3/ORDERS01//700">
<ns1:DATAHEADERCOLUMN_SEGNAM>E2EDKA1003</ns1:DATAHEADERCOLUMN_SEGNAM>
<ns1:PARVW>LF</ns1:PARVW>
<ns1:PARTN>0000100000</ns1:PARTN>
</ns1:E2EDKA1003>
<ns1:E2EDKA1003 xmlns:ns1="http://Microsoft.LobServices.Sap/2007/03/Types/Idoc/3/ORDERS01//700">
<ns1:DATAHEADERCOLUMN_SEGNAM>E2EDKA1003</ns1:DATAHEADERCOLUMN_SEGNAM>
<ns1:PARVW>ZC</ns1:PARVW>
<ns1:PARTN>
<xsl:choose>
<xsl:when test="@Transportation='1'">
<xsl:value-of select="'0000100001'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'0000100009'" />
</xsl:otherwise>
</xsl:choose>
</ns1:PARTN>
</ns1:E2EDKA1003>
In any of the cases that you decide to implement, if you try to compile or validate the map, everything will work fine, and the error will disappear.
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.