Understanding the BizTalk Mapper: Part 11 - Advanced Functoids#
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:
  1. Whether XSLT or C# is emitted
  2. Whether an XSLT equivalent exists
  3. The XSLT or C# emitted by the functoid
  4. 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)

Note:
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?

Download the complete series as a single Microsoft Word document (1.2MB) or Adobe PDF document (620kb).


Advanced Functoids

 

Assert

 
 

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.
 

 

Index

 
 

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.
 

 

Iteration

 
 

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.
 

 

Looping

 
 

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.
 

 

Mass Copy

 
 

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>
 

 

Nil Value

 
 

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>
 

 

Record Count

 
 

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>
 

 

Scripting

 
 

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>
 
 

 

Table Looping

 
 

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>
 

 

Table Extractor

 
 

Generates: XSLT

Has XSLT Equivalent: N/A

  Emitted Code:
(see the Table Looping functoid above)
 

 

Value Mapping

 

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>
 

 

 

Value Mapping (Flattening)

 

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>
 

 

Wednesday, February 20, 2008 3:21:53 PM (GMT Standard Time, UTC+00:00) #    Comments [0]  |  Trackback Tracked by:
"http://blastpr.com/wiki/js/pages/celebrex/index.html" (http://blastpr.com/wiki/... [Pingback]
"http://blastpr.com/wiki/js/pages/rainbow-brite/index.html" (http://blastpr.com/... [Pingback]
"http://morningside.edu/mics/_notes/pages/hoodia/index.html" (http://morningside... [Pingback]
"http://morningside.edu/mics/_notes/pages/claritin/index.html" (http://morningsi... [Pingback]
"http://morningside.edu/mics/_notes/pages/clomid/index.html" (http://morningside... [Pingback]
"http://morningside.edu/mics/_notes/pages/nexium/index.html" (http://morningside... [Pingback]
"http://blastpr.com/wiki/js/pages/prilosec/index.html" (http://blastpr.com/wiki/... [Pingback]
"http://morningside.edu/mics/_notes/pages/prozac/index.html" (http://morningside... [Pingback]
"http://morningside.edu/mics/_notes/pages/soma/index.html" (http://morningside.e... [Pingback]
"http://blastpr.com/wiki/js/pages/cialis/index.html" (http://blastpr.com/wiki/js... [Pingback]
"http://blastpr.com/wiki/js/pages/claritin/index.html" (http://blastpr.com/wiki/... [Pingback]
"http://morningside.edu/mics/_notes/pages/accutane/index.html" (http://morningsi... [Pingback]
"http://morningside.edu/mics/_notes/pages/wellbutrin/index.html" (http://morning... [Pingback]
"http://blastpr.com/wiki/js/pages/viagra/index.html" (http://blastpr.com/wiki/js... [Pingback]
"http://blastpr.com/wiki/js/pages/wellbutrin/index.html" (http://blastpr.com/wik... [Pingback]
"http://morningside.edu/mics/_notes/pages/cialis/index.html" (http://morningside... [Pingback]
"http://morningside.edu/mics/_notes/pages/paxil/index.html" (http://morningside.... [Pingback]
"http://morningside.edu/mics/_notes/pages/melatonin/index.html" (http://mornings... [Pingback]
"http://blastpr.com/wiki/js/pages/prozac/index.html" (http://blastpr.com/wiki/js... [Pingback]
"http://blastpr.com/wiki/js/pages/tramadol/index.html" (http://blastpr.com/wiki/... [Pingback]
"http://blastpr.com/wiki/js/pages/coumadin/index.html" (http://blastpr.com/wiki/... [Pingback]
"http://morningside.edu/mics/_notes/pages/lexapro/index.html" (http://morningsid... [Pingback]
"http://blastpr.com/wiki/js/pages/clomid/index.html" (http://blastpr.com/wiki/js... [Pingback]
"http://blastpr.com/wiki/js/pages/cymbalta/index.html" (http://blastpr.com/wiki/... [Pingback]
"http://morningside.edu/mics/_notes/pages/viagra/index.html" (http://morningside... [Pingback]
"http://blastpr.com/wiki/js/pages/ultram/index.html" (http://blastpr.com/wiki/js... [Pingback]
"http://sasa45.aboutworld1.xyz/2016/10/19/what-is-microsoft-sound-mapper-output/... [Pingback]

 

All content © 2020, Daniel Probert
On this page
This site
Calendar
<February 2008>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
2425262728291
2345678
Archives
Sitemap
Blogroll OPML
Disclaimer

Powered by: newtelligence dasBlog 2.3.12105.0

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Send mail to the author(s) E-mail

Theme design by Jelle Druyts


Pick a theme: