Answered by:
Set Xsi:Nil to true in the BizTalk map

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 schemaFor 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)
- Edited by Rachit SikroriaModerator Wednesday, May 25, 2016 6:44 AM clarity
- Proposed as answer by Angie Xu Thursday, June 2, 2016 7:38 AM
- Marked as answer by Angie Xu Thursday, June 2, 2016 7:38 AM
Wednesday, May 25, 2016 12:30 AMModerator
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 schemaFor 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)
- Edited by Rachit SikroriaModerator Wednesday, May 25, 2016 6:44 AM clarity
- Proposed as answer by Angie Xu Thursday, June 2, 2016 7:38 AM
- Marked as answer by Angie Xu Thursday, June 2, 2016 7:38 AM
Wednesday, May 25, 2016 12:30 AMModerator -
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 AMModerator -
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