locked
Set Xsi:Nil to true in the BizTalk map RRS feed

  • Question

  • I have requirement xsi:nil=true based on condition

    if phone="1234" 

    return phone 

    else 

    null.

    script functoid can't return null value and xslt template can't defined xsi nil attribute in the script functoid.

    Please provide your thoughts.

    Monday, May 23, 2016 9:38 PM

Answers

  • Hi Kapil,

    Refer: BizTalk Mapper: Working With Nillable Values (xsi:nil="true")

    Yes, scripting functoid won't work.

    You wil lget the error: "error btm1050: XSL transform error: Unable to write output instance to the following <file:///C:\…\MapNillValuesWithCustomXSLT_output.xml>. Prefix ‘xsi’ is not defined."

    The problem is that the nil attribute is defined in the XML Schema instance namespace, http://www.w3.org/2001/XMLSchema-instance (commonly associated with the prefix xsi) and this namespace is not declared by default in the XSL code generated by the BizTalk Mapper.

    Solution:

    You need check If element value is null you need to set a null value in the destination element also as null, otherwise we need to map the source value. To accomplish that we need to:

    - Drag one IsNil Functoid from the Toolbox window onto the Grid.
    - Drag a link from the “NillValue” field element in the source schema to the IsNill Functoid
    - Drag one Nil Value Functoid from the Toolbox window onto the Grid.
    - Drag one Logical NOT Functoid from the Toolbox window onto the Grid.
    - Drag one Value Mapping Functoid from the Toolbox window onto the Grid.
    - To create a rule for mapping the value if the element is null
    - Drag a link from the IsNill Functoid to the Nil Value Functoid
    - Drag a link from the Nil Value Functoid to the “NillValueOutput” field element in the destination schema
    - Otherwise, To create a rule for mapping the value if the element different of null
    - Drag a link from the IsNill Functoid to the Logical NOT Functoid
    - Drag a link from the Logical NOT Functoid to the Value Mapping Functoid Functoid
    - Drag a link from the “NillValue” field element in the source schema to the Value Mapping Functoid
    - Drag a link from the Value Mapping Functoid to the “NillValueOutput” field element in the destination schema

    For better performance the workaround is:

    - For only one of the nillable elements we need to use the Nil Functoids explained in the beginning of this post.
    This will declare automatically the name xsi namespace for us.
    -In the rest of the elements we now can use Scripting Functoids with the optimized XSLT code described below:

    <xsl:choose>
      <xsl:when test="NillValue/@xsi:nil">
        <NillValueOutput>
          <xsl:attribute name="xsi:nil">
            <xsl:value-of select="'true'" />
          </xsl:attribute>
        </NillValueOutput>
      </xsl:when>
      <xsl:otherwise>
        <NillValueOutput>
          <xsl:value-of select="NillValue/text()" />
        </NillValueOutput>
      </xsl:otherwise>
    </xsl:choose>



    Rachit Sikroria (Microsoft Azure MVP)


    Wednesday, May 25, 2016 12:30 AM
    Moderator

All replies

  • Hi Kapil,

    Refer: BizTalk Mapper: Working With Nillable Values (xsi:nil="true")

    Yes, scripting functoid won't work.

    You wil lget the error: "error btm1050: XSL transform error: Unable to write output instance to the following <file:///C:\…\MapNillValuesWithCustomXSLT_output.xml>. Prefix ‘xsi’ is not defined."

    The problem is that the nil attribute is defined in the XML Schema instance namespace, http://www.w3.org/2001/XMLSchema-instance (commonly associated with the prefix xsi) and this namespace is not declared by default in the XSL code generated by the BizTalk Mapper.

    Solution:

    You need check If element value is null you need to set a null value in the destination element also as null, otherwise we need to map the source value. To accomplish that we need to:

    - Drag one IsNil Functoid from the Toolbox window onto the Grid.
    - Drag a link from the “NillValue” field element in the source schema to the IsNill Functoid
    - Drag one Nil Value Functoid from the Toolbox window onto the Grid.
    - Drag one Logical NOT Functoid from the Toolbox window onto the Grid.
    - Drag one Value Mapping Functoid from the Toolbox window onto the Grid.
    - To create a rule for mapping the value if the element is null
    - Drag a link from the IsNill Functoid to the Nil Value Functoid
    - Drag a link from the Nil Value Functoid to the “NillValueOutput” field element in the destination schema
    - Otherwise, To create a rule for mapping the value if the element different of null
    - Drag a link from the IsNill Functoid to the Logical NOT Functoid
    - Drag a link from the Logical NOT Functoid to the Value Mapping Functoid Functoid
    - Drag a link from the “NillValue” field element in the source schema to the Value Mapping Functoid
    - Drag a link from the Value Mapping Functoid to the “NillValueOutput” field element in the destination schema

    For better performance the workaround is:

    - For only one of the nillable elements we need to use the Nil Functoids explained in the beginning of this post.
    This will declare automatically the name xsi namespace for us.
    -In the rest of the elements we now can use Scripting Functoids with the optimized XSLT code described below:

    <xsl:choose>
      <xsl:when test="NillValue/@xsi:nil">
        <NillValueOutput>
          <xsl:attribute name="xsi:nil">
            <xsl:value-of select="'true'" />
          </xsl:attribute>
        </NillValueOutput>
      </xsl:when>
      <xsl:otherwise>
        <NillValueOutput>
          <xsl:value-of select="NillValue/text()" />
        </NillValueOutput>
      </xsl:otherwise>
    </xsl:choose>



    Rachit Sikroria (Microsoft Azure MVP)


    Wednesday, May 25, 2016 12:30 AM
    Moderator
  • Hi Kapil,

    If you prefer doing the XSLT yourself: (I'm checking for missing element, empty value, and xsi:nil - delete accordingly if not applicable)

    <xsl:choose>
        <xsl:when test="not(s0:inElement) 
                        or s0:inElement[normalize-space(.) = ''] 
                        or string(s0:inElement/@xsi:nil) = 'true'">
            ... Default here, e.g. leave this blank, 
                ... or if you want nil then <ns1:outElement xsi:nil="true"/>
        </xsl:when>
        <xsl:otherwise>
            <ns1:outElement>
                <xsl:value-of select="s0:inElement/text()" />
            </ns1:outElement>
        </xsl:otherwise>
    </xsl:choose>
    refer : http://stackoverflow.com/questions/7822640/how-not-to-map-element-when-value-is-missing-in-biztalk


    Thanks,

    If my reply is helpful please mark as Answer or vote as Helpful.

    My blog | Twitter | LinkedIn

    This post is my own opinion and does not necessarily reflect the opinion or view of Microsoft, its employees, or other MVPs.

    Wednesday, May 25, 2016 4:12 AM
    Moderator
  • Hi

    I'm trying same technique but BizTalk is not appending attribute xsi:nil=true to the node when the node has empty/null value. BizTalk is producing empty node but I need to get null

    Any help?


    Maqsood Ahmad

    Monday, May 8, 2017 11:53 PM