Mapping from multiple source document with a key
In my last blog post I said that when I found more scenarios that required custom XSLT I would blog about it. I just didn’t think it would be quite so soon.
In this case I have two source documents and I needed to loop through one of them and select items off the other and map elements from both source documents to the destination document. I am working on this project with Matt Cable (who works for Quilogy and is in the Virtual TS for BizTalk program) and he showed me a great way to accomplish this (he looked over my shoulder as I was trying to figure something out and said it would be much easier to do it this way. I am very glad too because as I look back, what I was putting together was far more difficult).
So I have these two source documents (as shown in the screen shot below) and I need to loop through the bottom message and for every VendorUPC I need to match that up with the upper document and pull the Image and ImageThumb elements (it is not expanded in the screen shot but under the Color element there is a sku attribute that I can match up with the VendorUPC)
The following is what the XSLT looks like. We setup a for each loop around the bottom message at the record level. The ItemNumber and VendorUPC elements were easy as we could just take those from the current position in the loop. We were equally lucky with the URL element since it was not a repeating element and therefore we could grab that value.
The Image and ImageThumb is where it gets interesting. This is where we need to take the VendorUPC from the bottom document and match it up to the sku attribute in the top document and map the value. This is done through the code in the highlighted section. Everything in between the open and close brackets acts like a where clause. For this schema, the sku apears at a lower level in the hierarchy then the actual data that I needed to map. So in this case I am saying that at the xslt processor should look at /Color/Size/sku where that sku matches the current iterations VendorUPC. If there is a match then pick the /Color/pic_standard or /Color/pic_thumb attribute value and map that to the destination.
<xsl:for-each select="/*[local-name()='Root' and namespace-uri()='https://schemas.microsoft.com/BizTalk/2003/aggschema']/*[local-name()='InputMessagePart_1' and namespace-uri()='']/*[local-name()='MissingVendorImagesResponse' and namespace-uri()='https://MissingVendorImages']/*[local-name()='XXXXX_CatalogProducts' and namespace-uri()='https://MissingVendorImages']">
<ImageData>
<ItemNumber>
<xsl:value-of select="@ItemNo"/>
</ItemNumber>
<URL>
<xsl:value-of select="/*[local-name()='Root' and namespace-uri()='https://schemas.microsoft.com/BizTalk/2003/aggschema']/*[local-name()='InputMessagePart_0' and namespace-uri()='']/*[local-name()='ProductList' and namespace-uri()='']/@pic_url_prefix"/>
</URL>
<Image>
<xsl:value-of select="/*[local-name()='Root' and namespace-uri()='https://schemas.microsoft.com/BizTalk/2003/aggschema']/*[local-name()='InputMessagePart_0' and namespace-uri()='']/*[local-name()='ProductList' and namespace-uri()='']/*[local-name()='CatalogSection' and namespace-uri()='']/*[local-name()='Model' and namespace-uri()='']/*[local-name()='ColorVariations' and namespace-uri()='']/Color[Size/@sku = current()/@VendorUPC]/@pic_standard"/>
</Image>
<ImageThumb>
<xsl:value-of select="/*[local-name()='Root' and namespace-uri()='https://schemas.microsoft.com/BizTalk/2003/aggschema']/*[local-name()='InputMessagePart_0' and namespace-uri()='']/*[local-name()='ProductList' and namespace-uri()='']/*[local-name()='CatalogSection' and namespace-uri()='']/*[local-name()='Model' and namespace-uri()='']/*[local-name()='ColorVariations' and namespace-uri()='']/Color[Size/@sku = current()/@VendorUPC]/@pic_thumb"/>
</ImageThumb>
<VendorUPC>
<xsl:value-of select="@VendorUPC"/>
</VendorUPC>
</ImageData>
</xsl:for-each>