BizTalk Mapper tips and tricks: How to solve prefix problems (Exception Caught: ‘ns1’ is an undeclared prefix) in inline XSLT scripts

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)

BizTalk Mapper inline scriptin functoid with prefix
<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">
BizTalk Mapper xslt prefix namespace

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.

Author: Sandro Pereira

Sandro Pereira lives in Portugal and works as a consultant at DevScope. In the past years, he has been working on implementing Integration scenarios both on-premises and cloud for various clients, each with different scenarios from a technical point of view, size, and criticality, using Microsoft Azure, Microsoft BizTalk Server and different technologies like AS2, EDI, RosettaNet, SAP, TIBCO etc. He is a regular blogger, international speaker, and technical reviewer of several BizTalk books all focused on Integration. He is also the author of the book “BizTalk Mapping Patterns & Best Practices”. He has been awarded MVP since 2011 for his contributions to the integration community.

Leave a Reply

Your email address will not be published. Required fields are marked *

turbo360

Back to Top