Interestingly, all of the advanced functoids emit XSLT. No C# in sight at all.
The reason for this is that the functoids in this category all perform operations
best suited to trees of data i.e. XML.
The only way to do this in C# would be to load the data into a DOM (i.e. XmlDocument)
or XmlReader, or treat the XML as string data and search for tokens.
Note: this category was the one that actually started this series – I felt
that if you knew the XSLT emitted by these functoids it would help understand when
to use them, and what you can achieve with them.
For each functoid I’ve shown:
- Whether XSLT or C# is emitted
- Whether an XSLT equivalent exists
- The XSLT or C# emitted by the functoid
-
Where C# is emitted, the equivalent XSLT to achieve the same functionality (in both
XSLT v1.0 and v2.0)
Functoids covered in this category:
Assert | Record Count |
Index | Scripting |
Iteration | Table Looping |
Looping | Table Extractor |
Mass Copy | Value Mapping |
Nil Value | Value Mapping (Flattening) |
This is the eleventh in a series of 13 posts about the BizTalk Mapper.
The other posts in this series are (links will become active as the posts become active):
Understanding
the BizTalk Mapper: Part 1 – Introduction
Understanding
the BizTalk Mapper: Part 2 – Functoids Overview
Understanding
the BizTalk Mapper: Part 3 – String Functoids
Understanding
the BizTalk Mapper: Part 4 – Mathematical Functoids
Understanding
the BizTalk Mapper: Part 5 – Logical Functoids
Understanding
the BizTalk Mapper: Part 6 – Date/Time Functoids
Understanding
the BizTalk Mapper: Part 7 – Conversion Functoids
Understanding
the BizTalk Mapper: Part 8 – Scientific Functoids
Understanding
the BizTalk Mapper: Part 9 – Cumulative Functoids
Understanding
the BizTalk Mapper: Part 10 – Database Functoids
Understanding the BizTalk Mapper: Part 11 – Advanced Functoids
Understanding the BizTalk Mapper: Part 12 – Performance and Maintainability
Understanding the BizTalk Mapper: Part 13 – Is the Mapper the best choice for Transformation
in BizTalk?
When all of the above have been posted, the entire series will be downloadable as
a single Microsoft Word document, or Adobe PDF file.
Advanced Functoids |
||
|
||
Generates: XSLT |
Has XSLT Equivalent: N/A |
|
Emitted Code: <xsl:if test=“(value-test)=’false’“> <xsl:message terminate=“yes“> <xsl:value-of select=“(value-error)“ /> </xsl:message> </xsl:if> <xsl:if test=“(value-test)=’true’“> <xsl:variable name=“var:v1“ select=“(value-out)“ /> <xsl:value-of select=“$var:v1“ /> </xsl:if> Note: (value-test) is the element/attribute/value tested for a true/false value. (value-error) is the element/attribute/value used as the error text. (value-out) is the element/attribute/value emitted if there is no error. |
||
|
||
Generates: XSLT |
Has XSLT Equivalent: N/A |
|
Emitted Code: <xsl:variable name=“var:v1“ select=“./(node)[index][index][…]/(element)/(attribute)“ /> for example: <xsl:variable name=“var:v1“ select=“./Employee[2]/@id“ /> Note: in the above code, Employee is the repeating node, 2 is the index we want to use, and @id is an attribute of the Employee element we wish to retrieve. This functoid uses standard XSLT indexing to build up an XSLT select query. The sample code shown above is a very simple example. |
||
|
||
Generates: XSLT |
Has XSLT Equivalent: N/A |
|
Emitted Code:
<xsl:variable name=“var:v1“ select=“position()“ /> |
||
Note: the functoid places the above code under the relevant element we’re getting the iteration (index) of. The variable is then used to emit the index at the appropriate place. |
||
|
||
Generates: XSLT |
Has XSLT Equivalent: N/A |
|
Emitted Code: <xsl:for-each select=“(node)“> </xsl:for-each> Note: where (node) is whatever input node is being looped-over. The Looping functoid is unique in that if you link from a repeating node in the source tree, then the Mapper will implicitly insert a looping functoid (although no functoid shape will be visible on the map). Understanding how to use the looping functoid is a vital part of creating advanced maps (e.g. concatenating multiple messages into one, or flattening loops). If you have more than one input element into the loop, then a for-each loop is created over each input element, and one output element is created for each input element. This is a common way of concatenating (aggregating) two separate messages. |
||
|
||
Generates: XSLT |
Has XSLT Equivalent: N/A |
|
Emitted Code: <xsl:copy-of select=“./@*“ /> <xsl:copy-of select=“./*“ /> Note: the functoid places the above code under the appropriate destination element, and the “.” indicates the current element being processed from the source message. As an example: <ns0:Employees> <xsl:for-each select=“Employee“> <Employee> <xsl:copy-of select=“./@*“ /> <xsl:copy-of select=“./*“ /> </Employee> </xsl:for-each> </ns0:Employees> |
||
|
||
Generates: XSLT |
Has XSLT Equivalent: N/A |
|
Emitted Code: <xsl:attribute name=“xsi:nil“> <xsl:value-of select=“‘true’“ /> </xsl:attribute> Note: the functoid places the above code under the appropriate element in the destination message. If a parameter is supplied to the functoid, then the above code is wrapped in an <xsl:if> node. For example: <xsl:if test=“@name=’true’“> <Field> <xsl:attribute name=“xsi:nil“> <xsl:value-of select=“‘true’“ /> </xsl:attribute> </Field> </xsl:if> |
||
|
||
Generates: XSLT |
Has XSLT Equivalent: N/A |
|
Emitted Code: <xsl:variable name=“var:v1“ select=“count(node-set)“ /> Note: (node-set) is an element/record which repeats. The variable is then used in a value-of statement. For example: <xsl:variable name=“var:v1“ select=“count(/ns0:Employees/Employee)“ /> <ns0:Employees> <Employee> <xsl:attribute name=“id“> <xsl:value-of select=“$var:v1“ /> </xsl:attribute> </Employee> </ns0:Employees> |
||
|
||
Generates: XSLT/Inline Script |
Has XSLT Equivalent: N/A |
|
Emitted Code: External Assembly Emits XSLT to call the appropriate method, along with an Extension Object file containing the strong name of the assembly to use. For example (this example passes in two constant parameters to the method): <xsl:variable name=“var:v1“ select=“ScriptNS0:AddComponent(‘1’, ‘2’)“ /> <xsl:value-of select=“$var:v1“ /> <ExtensionObjects> <ExtensionObject Namespace=“http://schemas.microsoft.com/BizTalk/2003/ScriptNS0“ AssemblyName=“Microsoft.BizTalk.DefaultPipelines, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35“ ClassName=“Microsoft.BizTalk.DefaultPipelines.PassThruReceive“ /> </ExtensionObjects> Inline C# Inline JScript .NET Inline Visual Basic .NET Emits a call to the method, and wraps the actual code in a CDATA block. For example: <xsl:variable name=“var:v1“ select=“userC#:MyConcat’1′, ‘2’)“ /> <xsl:value-of select=“$var:v1“ /> <msxsl:script language=“C#“ implements-prefix=“userC#“><![CDATA[ ///*Uncomment the following code for a sample Inline C# function //that concatenates two inputs. Change the number of parameters of //this function to be equal to the number of inputs connected to this functoid.*/ public string MyConcat(string param1, string param2) { return param1+param2; } ]]> </msxsl:script> Inline XSLT Emits the XSLT as entered at the appropriate place in the destination tree. Inline XSLT Call Template Emits the template and a call to the template. For example: <xsl:call-template name=“MyXsltConcatTemplate“> <xsl:with-param name=“param1“ select=“‘1’“ /> <xsl:with-param name=“param2“ select=“‘2’“ /> </xsl:call-template> <xsl:template name=“MyXsltConcatTemplate“> <xsl:param name=“param1“ /> <xsl:param name=“param2“ /> <xsl:element name=“field“> <xsl:value-of select=“$param1“ /> <xsl:value-of select=“$param2“ /> </xsl:element> </xsl:template> |
||
|
||
Generates: XSLT |
Has XSLT Equivalent: N/A |
|
Emitted Code: (auto generated) Note: the Table Looping functoid (along with the Table Extractor functoid) builds custom XSLT in the destination XSLT. This custom XSLT will comprise a number of for-each loops (for the repeating element specified as the first parameter to the Table Looping functoid), and then a number of structures, one per row configured in the functoid. If the Gated property is set, then each structure is surrounded by an if statement. This is an example of the output generated by use of the Table Looping / Table Extractor functoids. In this sample, we’re filtering the input list, so that the output only contains Employee nodes with a department value of ‘Managers’. In this example, the Table Looping functoid has the source Employee element as input, with number of columns set to 5, followed by a Logical Equal functoid (true if @department equals ‘managers’, followed by a single constants (Management) and then three attributes (@name, @id, @department). The sample XML used as input was: <ns0:Employees xmlns:ns0=“http://TestMaps.Employees“> <Employee name=“Mary Briggs“ id=“1“ department=“Managers“ /> <Employee name=“Sam Gamgee“ id=“5“ department=“Staff“ /> <Employee name=“Frodo Smith“ id=“20“ department=“Staff“ /> </ns0:Employees> The looping functoid was then setup to generate one record (row) per input element, with the Gated property set on the first column the Logical Equal functoid). Four Table Extractor functoids were setup, with each one connecting to one of the four attributes on the output message (@type, @name, @id, @department). This is the XSLT generated by these functoids: <xsl:template match=“/s0:Employees“> <ns0:Employees> <xsl:for-each select=“Employee“> <xsl:variable name=“var:v1“ select=“userCSharp:LogicalEq(string(@department), ‘Managers’)“ /> <xsl:if test=“$var:v1“> <xsl:variable name=“var:v2“ select=“‘Management’“ /> <xsl:variable name=“var:v3“ select=“@name“ /> <xsl:variable name=“var:v4“ select=“@id“ /> <xsl:variable name=“var:v5“ select=“@department“ /> <Employee> <xsl:attribute name=“type“> <xsl:value-of select=“$var:v2“ /> </xsl:attribute> <xsl:attribute name=“name“> <xsl:value-of select=“$var:v3“ /> </xsl:attribute> <xsl:attribute name=“id“> <xsl:value-of select=“$var:v4“ /> </xsl:attribute> <xsl:attribute name=“department“> <xsl:value-of select=“$var:v5“ /> </xsl:attribute> </Employee> </xsl:if> </xsl:for-each> </ns0:Employees> </xsl:template> |
||
|
||
Generates: XSLT |
Has XSLT Equivalent: N/A |
|
Emitted Code: (see the Table Looping functoid above) |
||
|
||
Generates: XSLT |
Has XSLT Equivalent: N/A |
|
Emitted Code: <xsl:for-each select=“(source element)“> <(destination element parent)> <xsl:if test=“(node-test)=’true’“> <xsl:variable name=“var:v1“ select=“@id“ /> <(destination element)> <xsl:value-of select=“$var:v1“ /> </(destination element)> </xsl:if> </(destination element parent)> </xsl:for-each> Note: if the Value Mapping functoid is used with a repeating source element, then it will place a for-each element outside of the parent destination element. If the source element is not repeating, then the functoid emits a value-of statement, with an optional if statement (if an element/attribute is used as the first parameter rather than a constant). For example, if the input message was: <ns0:Employees xmlns:ns0=“http://TestMaps.Employees“> <Employee name=“Mary Briggs“ id=“1“ department=“Managers“ /> <Employee name=“Sam Gamgee“ id=“5“ department=“Staff“ /> <Employee name=“Frodo Smith“ id=“20“ department=“Staff“ /> </ns0:Employees> and the source/destination schemas were the schema used for the above message, and the Value Mapping functoid linked the id attribute to the Field element, then the following XSLT would be generated: <ns0:Employees> <xsl:for-each select=“Employee“> <xsl:variable name=“var:v1“ select=“@id“ /> <Employee> <Field> <xsl:value-of select=“$var:v1“ /> </Field> </Employee> </xsl:for-each> </ns0:Employees> which would generate the following output: <ns0:Employees xmlns:ns0=“http://TestMaps.Employees“> <Employee> <Field>1</Field> </Employee> <Employee> <Field>5</Field> </Employee> <Employee> <Field>20</Field> </Employee> </ns0:Employees> |
||
|
||
|
||
Generates: XSLT |
Has XSLT Equivalent: N/A |
|
Emitted Code: <(destination element parent)> <xsl:for-each select=“(source element)“> <xsl:if test=“(node-test)=’true’“> <xsl:variable name=“var:v1“ select=“(source-value)“ /> <(destination element)> <xsl:value-of select=“$var:v1“ /> </(destination element)> </xsl:if> </xsl:for-each> </(destination element parent)> Note: the Value Mapping (Flattening) functoid constructs a for-each loop around the source element, and outputs one instance of the destination element per instance of the source element. For example, if the input message was: <ns0:Employees xmlns:ns0=“http://TestMaps.Employees“> <Employee name=“name_0“ id=“1“ department=“department_2“ /> <Employee name=“name_0“ id=“5“ department=“department_2“ /> <Employee name=“name_0“ id=“20“ department=“department_2“ /> </ns0:Employees> and the source/destination schemas were the schema used for the above message, and the Value Mapping (Flattening) functoid linked the id attribute to the Field element, then the following XSLT would be generated: <ns0:Employees> <Employee> <xsl:for-each select=“Employee“> <xsl:variable name=“var:v1“ select=“@id“ /> <Field> <xsl:value-of select=“$var:v1“ /> </Field> </xsl:for-each> </Employee> </ns0:Employees> which would generate the following output: <ns0:Employees xmlns:ns0=“http://TestMaps.Employees“> <Employee> <Field>1</Field> <Field>5</Field> <Field>20</Field> </Employee> </ns0:Employees> |
||
|