BizTalk Map using custom XSLT
March 3, 2012 2 Comments
Problem
There is a requirement to generate output XML based on the attributes of input XML:
Following is my Input xml schema
And our output schema looks like below
I have to map the “Property” and its attribute “Name” based on the values and name of the input schema “Branch” record. for each “Branch” in the input there should be one record of the “Location” in the output schema.
For example if below is our input XML :
Then my output XML should be like below
If you see in the output XML the property and its values are populated on the basis of incoming records in “Branch”.
Solution
I would do following to achieve this requirement, My favorite custom XSLT in BizTalk Maps:
It is very easy to generate a Custom XSLT, BizTalk Map generates the basic code for the schema namespace etc and then we can always modify it.
Steps:
- Add a new MAP in the BizTalk project
- Choose the input schema and output schema
- after this the MAP should look like below:
- start mapping the elements and records from input to output. So simple
- We have to map the value of “Availability” to the value of “Property” and the “Name” attribute should be populated with “Availability” , So I would simply connect “Availability” to “Property” and use a concatenation functoid to assign the attribute “Name” to “Availability” . My map Will look something like below:
- Now I will generate my basic XSLT code which i will further modify. I will validate the MAP and after the validation I will get the basic XSLT which i will modify.
- Right Click on the map in the solution explorer and Click “Validate” , Check the Visual Studio output window, there will be a message something like below
- Open the XSL file highlighted and save that in the BizTalk solution . Now we can modify this XSL file and use in our MAP.
- to use the XSL file in our MAP we would need to delete all the links which we have done in the above steps and use the “Custom XSLT Path” property of the BizTalk MAP,
- Delete all the links in the map
- Open the MAP property and select the path of the XSL file which we have saved earlier.
- After that my map looks like below:
- And we can now test the map using our Input.
- The final XSLT looks like below, which does all the mapping.
<xsl:output omit-xml-declaration=”yes” method=”xml” version=”1.0″ />
<xsl:template match=”/”>
<xsl:apply-templates select=”/s0:QueryInput” />
</xsl:template>
<xsl:template match=”/s0:QueryInput”>
<ns0:QueryResponse>
<xsl:for-each select=”s0:Branch”>
<xsl:variable name=”var:v1″ select=”userCSharp:StringConcat("OnOrder")” />
<xsl:variable name=”var:v2″ select=”userCSharp:StringConcat("ETA")” />
<xsl:variable name=”var:v3″ select=”userCSharp:StringConcat("Availability")” />
<ns0:Location>
<ns0:Name>
<xsl:value-of select=”@Name” />
</ns0:Name>
<ns0:Quantity>
<xsl:value-of select=”s0:Availability/text()” />
</ns0:Quantity>
<ns0:Property>
<xsl:attribute name=”Name”>
<xsl:value-of select=”$var:v3″ />
</xsl:attribute>
<xsl:value-of select=”s0:Availability/text()” />
</ns0:Property>
<ns0:Property>
<xsl:attribute name=”Name”>
<xsl:value-of select=”$var:v1″ />
</xsl:attribute>
<xsl:value-of select=”s0:OnOrder/text()” />
</ns0:Property>
<ns0:Property>
<xsl:attribute name=”Name”>
<xsl:value-of select=”$var:v3″ />
</xsl:attribute>
<xsl:value-of select=”s0:ETA/text()” />
</ns0:Property>
<xsl:value-of select=”./text()” />
</ns0:Location>
</xsl:for-each>
</ns0:QueryResponse>
</xsl:template>
<msxsl:script language=”C#” implements-prefix=”userCSharp”><![CDATA[
public string StringConcat(string param0)
{
return param0;
}]]></msxsl:script>
</xsl:stylesheet>
Hope it helps!
Thanks for reading!