In the last few days, a customer asked me an interesting question about mapping xsi:nil attributes in the Biztalk 2004 mapper.  In Biztalk 2006, there are a couple of new functoids which help with mapping these attributes, but unfortunately there is no easy way to handle these conditionally in the 2004 mapper.  Fortunately, with some knowledge of XSLT, you can achieve the same functionality with Biztalk 2004 today.  I've published an explanation of the problem and a quick mapper solution here and hopefully some of you may benefit from the approach.

Customer Problem

The customer has a source schema which contains elements that are nillable (i.e. the nillable attribute is set on a number of elements).  The Biztalk 2004 mapper does not provide any means to detect the presence or absence of the xsi:nil attribute in an instance document, therefore it seems 'impossible' to do conditional mapping based on this attribute.

For each element that is nillable, the customer needs to copy the value of the element (if any) to a node in the destination schema.  They want to use an accompanying boolean node to indicate whether or not the element is set to nil in the input instance document.

 

Example of Source Schema (Contains nillable elements)

Example of Destination Schema

 


Solution

Being a developer, my first approach was to try to write a custom functoid for 2004 to emulate the functionality in 2006.  Hey, it shouldn't be that hard, right?  Unfortunately looking at the published SDK samples it appears that functoids take either the name of the node or value of the node as inputs (depending on how the link is configured).  Therefore, on the surface, there doesn't appear to be a way to pass a reference to the node itself, nor any easy way to get a reference to the original node.

My next approach was to try an inline XSLT template via the Scripting functoid.  Luckily this worked fine so I abandoned the custom functoid approach..!  This technique appears unintuitive to me due to 'lack of context'.  By this I mean that there is no immediately obvious way to get the node reference (just the name or contents) as input, and therefore it is likely to be difficult to work out whether or not an instance node has the nil attribute set in map.

Fortunately, the XSLT call template is called within the current node 'context'.   I discovered this by displaying the name of the current node and running some tests of the map.  The Biztalk mapper makes it quite easy to experiment with and test maps and since you can always examine the generated XSLT, it isn't really that hard to figure out how things are (or aren't) working.  The screenshots below show the approach I used:

Here is the mapper surface:

..and here is the detail of the Scripting (Inline XSLT) functoid:

In summary, the best reusable approach would be to make use of the functionality in 2006, but if that isn't an option then the technique described here may well work out for you.  I guess I should sign off with a summary of the pro's and con's, so that you can make your own mind up as to whether this approach will work for you.

 

Pros: Quick to implement, no need to write additional code outside the mapper, Handles xsi:nils, Approach can be generally applied to handle any attribute not supported by the mapper

Cons: Less intuitive, doesn't replace a generic function, requires XSLT knowledge (I would argue that you should learn this anyway if you're attempting to use the mapper since it makes things a lot easier), name of the target node is fixed in the XSLT template.

 

Happy mapping! [:)]

Roy.