xslt-1.0biztalkbiztalk-2013

Set an xslt variable with an email


In a BizTalk mapper, I had to set a default e-mail in output field when a specific input field is null or empty.

So I set an XSLT variable with the email but when the condition is good no node is created in the output.

Here is my code:

<xsl:template name="GetEmail">
  <xsl:param name="number" />
  <xsl:param name="Email" />
  <xsl:variable name="defaultmail">noreply&#64;domain.fr</xsl:variable>

  <xsl:for-each select="//*[local-name()='Employee']">
    <xsl:choose>
      <xsl:when test="*[local-name()='Username' and text() = $number] and $Email != ''">
        <xsl:element name="email">      
          <xsl:value-of select="string(*[local-name()='Email'])" />
        </xsl:element>
      </xsl:when>
      <xsl:when test="*[local-name()='Username' and text() = $number] and $Email = ''">
        <xsl:element name="email">      
          <xsl:value-of select="$defaultmail" />
        </xsl:element>
      </xsl:when>
    </xsl:choose>
  </xsl:for-each>      
</xsl:template>

Here is my Input file:

<ns0:Root xmlns:ns0="http://schemas.microsoft.com/BizTalk/2003/aggschema">
    <InputMessagePart_0>
        <Get>
            <Employee>
                <Username>008441</Username>
                <Email />
            </Employee>
            <Employee>
                <Username>014095</Username>
                <Email>email2@domain.fr</Email>
            </Employee>
            <Employee>
                <Username>011812</Username>
                <Email>email3@domain.fr</Email>
            </Employee>
        </Get>
    </InputMessagePart_0>
    <InputMessagePart_1>
        <ns1:EmployeeResponse xmlns:ns1="http://Employee">
            <ns1:Header /> 
            <ns1:Return>
                <ns1:Employee>
                    <ns1:Number>008441</ns1:Number>
                </ns1:Employee>
            </ns1:Return>
        </ns1:EmployeeResponse>
    </InputMessagePart_1>
</ns0:Root>

And here is the output:

<Employee>
  <username>123456789</username> 
  <firstname>Firstname</firstname> 
  <lastname>Lastname</lastname>
  <birthdate>dd/MM/yyyy</birthdate>
<email />
</Employee>

And what it should be:

<Employee>
  <username>123456789</username> 
  <firstname>Firstname</firstname> 
  <lastname>Lastname</lastname>
  <email>noreply@domain.fr</email>
  <birthdate>dd/MM/yyyy</birthdate>
</Employee>

I have 2 input files, one is provided by my customer and the other is provided by our DB. The first file from customer contains a list of employees. The second file from our DB contains only one employee identified with the Username in the first file. There is a loop so for each employee in the first file we get the employee datas related to Username. We need two datas in our DB related to each employee to calculate 2 fields in output file. The output must contains all datas from the first one and the 2 calculated fields. If the email field is not provided (empty or null) in the first file (from my customer), BizTalk mapper take the email of the next employee with an non empty email field. So in my example, the output will be:

<Employee>
  <username>008441</username> 
  <firstname>Firstname</firstname> 
  <lastname>Lastname</lastname>
  <email>email2@domain.fr</email>
  <birthdate>dd/MM/yyyy</birthdate>
</Employee>

instead of :

<Employee>
  <username>008441</username> 
  <firstname>Firstname</firstname> 
  <lastname>Lastname</lastname>
  <email>noreply@domain.fr</email>
  <birthdate>dd/MM/yyyy</birthdate>
</Employee>

Solution

  • You should NOT try to link from both InputMessagePart_0 and InputMessagePart_1, that just confuses the looping, and you are already creating the loop inside the XSLT for InputMessagePart_0 with your for-each-select. Just link the Number from InputMessagePart_1 and use the following XSLT. Also select the Email from the node, and not pass it in as a variable.

    <xsl:template name="GetEmail">
      <xsl:param name="number" />
      <xsl:variable name="defaultmail">noreply&#64;domain.fr</xsl:variable>
    
      <xsl:for-each select="//*[local-name()='Employee']">
        <xsl:choose>
          <xsl:when test="*[local-name()='Username' and text() = $number]">
           <xsl:choose>
             <xsl:when test="*[local-name()='Email' and text() != '']">
               <xsl:element name="email">
                <xsl:value-of select="string(*[local-name()='Email'])" />
               </xsl:element>
             </xsl:when>
               <xsl:otherwise>
               <xsl:element name="email">      
                 <xsl:value-of select="$defaultmail" />
               </xsl:element>
             </xsl:otherwise>
           </xsl:choose>
         </xsl:when>
        </xsl:choose>
      </xsl:for-each>      
    </xsl:template>