prefixes in inline XSLT scripts

BizTalk Server Best practices, Tips, and Tricks: #16 Using prefixes in inline XSLT scripts

Published on : May 19, 2023

Category : BizTalk Server

Sandro

Author

Welcome again to another BizTalk Server Best practices, Tips, and Tricks blog post! In my previous blog posts, I discussed some essential tips and tricks for BizTalk Server administrators:

And for BizTalk Server Developers:

Today I will speak about another critical Best practice, Tips and Tricks, this time for BizTalk Server developers: Using prefixes in inline XSLT scripts inside your BizTalk Server maps.

prefixes in inline XSLT scripts

#16 Using prefixes in inline XSLT scripts

XML Namespaces provide a method to avoid element name conflicts: XML namespace prefixes. And, of course, all of these capabilities are fully supported inside BizTalk Server.

When we are working with the BizTalk Server Mapper Editor and mapping using our messages using direct links of a Functoid or a chain of Functoids, by default, we don’t need to worry about dealing with namespaces or prefixes because the editor will be smart enough to deal with them and set them correctly.

However, for several reasons, sometimes we need to use custom inline XSLT scripts in our transformations. Again, I can spend many hours discussing this topic, but you can always learn more about this topic in my free book: BizTalk Mapping Patterns & Best Practices.

prefixes in inline XSLT scripts

But to short, one of the reasons will be grouping or joining different records based on some conditions.

An excellent typical sample of these types of schemas that contains several prefixes are SAP IDOC schemas:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:msxsl="urn:schemas-microsoft-com:xslt"
     

 

Note, for example, the existence of the prefix ns1 that we will use in several structures inside the SAP IDoc schema.

Now if we were trying to map the E2EDKA1003 structure without a prefix, that would look like this:

prefixes in inline XSLT scripts

And if you are not an experienced XSLT user, probably the code you endup doing was something like this:

<E2EDKA1003>
  <DATAHEADERCOLUMN_SEGNAM>E2EDKA1003</DATAHEADERCOLUMN_SEGNAM>
  <PARVW>ZC</PARVW>
  <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>
  </PARTN>
</E2EDKA1003>

 

The problem with the code above is that if we test out mapping, we will see that that code will create the structures without the mandatory prefixes. 

Of course, that is not what we want because that structure needs to use the prefix ns1—saying that now the main question is how to add this prefix to our inline code.

If you try to add directly to the element:

<ns1:E2EDKA1003>
  <ns1:DATAHEADERCOLUMN_SEGNAM>E2EDKA1003</ns1:DATAHEADERCOLUMN_SEGNAM>

 

That will not work. You will get an Exception Caught: ‘ns1’ is an undeclared prefix. Line …, position … if you try to compile the map.

In these cases, the best option you have in hand is not to directly create the structure of the message inside the XSLT code and instead, use the <xsl:element> element or <xsl:attribute> element to create the records, elements, and attributes required.

<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, you can continue to create the structure of the message inside the XSLT code, but on that case, you need to declare the prefix namespace in the record:

  <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 you can decide what best approach you want to implement in your maps,
 
Stay tuned for the upcoming BizTalk Server Best practices, Tips, and Tricks.