The only examples I could find was this forum question . The forum Q&A is not clear and suggested that one has to use a series of call templates with specific matches which seemed way to complicated to me. In this article show how I solved this another way. Consider the following BizTalk map which loops over several repeating records using a xsl:for-each.
The XSLT behind the scenes, with the unimportant bits hidden from view, does this ( note the xsl:for-each statements;
How do we iterate over every repeating node in the Variants loop when we are in Masters loop? We want to select and then to add the content of several Variants sub nodes contents to the destination message while we are processing the Masters loop. Using a functoid chain just did not seem to work and I decided to use a custom XSLT call template in a scripting functoid as shown below. I only resort to custom XSLT in complex mapping when simple functoids just will not work and this seems to be such a case.
The first scripting functoid takes a ProdID and converts this to a randomised path (I talked about this in my previous blog article). This is sent to the second XSLT call template scripting functoid which is the subject of this article. The subtraction functoid that also feed the XSLT call template is linked to a element called NumofImages. The final input to the XSLT call template is element called ProdMaster which links all the variant products to the master products.
My first attempt at the XSLT call template was
This gave the desired output and I was pleased but…
On adding this template to the XSLT Scripting template I was puzzled because I only got the top child image group and none of the grandparent image groups.
I was puzzled for a bit but then I realised that my custom XSLT test was not quite the same as what is happening in BizTalk Map. Within the BizTalk we are in a for each loop that was started with xsl:for-each select=”Masters”><xsl:for-each select=”s0:InternalProduct”>. If add this in to the XSLT call template then I can reproduce the non-desirable XML
The problem line is <xsl:for-each select=”Variants”> because when you inside the other loop, this node cannot be found like this. I tried to use the ancestor axis like <xsl:for-each select=”ancestor::Variants”> but this did not work because I was still one node to low in the xml. Finally I tried
and everything worked in the BizTalk Map. The ../.. is shorthand for select the grandparent of a child.
In summary I have shown an example of how to access a Grandparent loop from within a GrandChild loop in a BizTalk map using a custom XSLT template. If you want to see a version of the final XSLT is can be downloaded here.