Back again to one of my favorites topics: transformations. This is something that several people asked me for help in the past but I never found time to reply… until now.
A quite note: if you want to know more about BizTalk Maps transformation check out my free book available at BizTalk360 website: BizTalk Mapping Patterns & Best Practices
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) contains 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 in lint 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, 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 he 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 create 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 case that you decide to implement, if then you try to compile or validate the map, everything will work fine and the error will disappear.