Creating a specific number of elements in destination of map.

by eliasen 6. oktober 2007 22:09

Hi

A guy on the newsgroups recently needed to create exactly 5 elements in the output of his map, no matter how many records appeared in the input.

Well, I am always looking for new things to try out, and frankly, my XSLT coding skills could be better, so I thought I'd give it a shot.

I created a project with the following input schema:

The schema is for an XML document, and has a header (1..1), a LoopingRecord (1..1) and a footer (1..1). The LoopingRecord has a Field5 element, that can appear at most 5 times.

The output schema looks like this:

This schema is for a flat file. It baiscally has the same signature as the input schema - exception being that the Field1 element has minOccurs=5. It MUST be present 5 times - this is a schema for a positional file.

The map is pretty simple:

Header and footer are mapped using regular mapping techniques. But the Detail-element is created using a custom scripting functoid.

The string concatenate functoid only has one input, the string "5". This is because I want to create exactly 5 elements in the ouput.

The custom scripting functoid is an "Inline XSLT Call TEmplate" scripting functoid with the following code:

<xsl:template name="CreateXElements">
   <xsl:param name="totalCount" />
      <Detail>
         <xsl:for-each select="/*[local-name()='InputRoot']/*[local-name()='LoopingRecord']/*[local-name()='Field5']">
            <DetailLoop>
               <Field1><xsl:value-of select="text()" /></Field1>
            </DetailLoop>
         </xsl:for-each>
         <xsl:variable name="countRecords" select="count(/*[local-name()='InputRoot']/*[local-name()='LoopingRecord']/*[local-name()='Field5'])" />
         <xsl:if test="$countRecords&lt;$totalCount + 1">
            <xsl:call-template name="BuildTheRest">
               <xsl:with-param name="counter"><xsl:value-of select="$countRecords + 1" /></xsl:with-param>
               <xsl:with-param name="totalCount"><xsl:value-of select="$totalCount" /></xsl:with-param>
            </xsl:call-template>
         </xsl:if>
      </Detail>
</xsl:template>
<xsl:template name="BuildTheRest">
   <xsl:param name="counter" />
   <xsl:param name="totalCount" />
      <DetailLoop>
         <Field1></Field1>
      </DetailLoop>
      <xsl:if test="$counter&lt;$totalCount">
         <xsl:call-template name="BuildTheRest">
            <xsl:with-param name="newCounter"><xsl:value-of select="$counter + 1" /></xsl:with-param>
         </xsl:call-template>
      </xsl:if>
</xsl:template>

Basically, I start by copying existing nodes to the destination. As I have explained in this post you need to use XSLT for the whole thing. You can't copy the existing nodes using the mapper and create the new nodes using XSLT. After the existing nodes have been copied, I create the new empty nodes, by recursively calling a template that will create a single element for me.

You can find my entire project here: CreateXNumberOfElements.zip (23.33 KB)

I hope this will come in handy for someone in the future.

--
eliasen

Tags:

BizTalk 2006

Comments (4) -

Glenn
Glenn
09-10-2007 18:56:03 #

Thanks for the followup on this item.  I was able to get the input schema changed to have exactly 5 entries, but this solution will work for me in the future also.

Reply

dunker
dunker
10-03-2008 11:34:45 #

Hi, thanks for the entry, it was helpfull to understand, how xslt templates work.
I am looking for a example, how i can get input instances from functoids in the inline xslt script. is it possible?

Reply

Jan Eliasen
Jan Eliasen
10-03-2008 21:52:19 #

Hi

Yeah, that should be possible. But only the call template will work with parameters. You can do it with the inline XSLT scripting functoid.

--
eliasen

Reply

Christian Laverdiere
Christian Laverdiere
17-07-2008 18:18:51 #

You might also want to take a look at the table looping functoid. that's exactly what it's design for.

Have a nice day,
Chris

Reply

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading

About the author

Jan Eliasen is 37 years old, divorced and has 2 sons, Andreas (July 2004) and Emil (July 2006).

Jan has a masters degree in computer science and is currently employed at Logica Denmark as an IT architect.

Jan is a 6 times Microsoft MVP in BizTalk Server (not currently an MVP) and proud co-author of the BizTalk 2010 Unleashed book.

BizTalk Server 2010 Unleashed


Buy from Amazon

Microsoft MVP


6 times: July 2004, July 2008, July 2009, July 2010, July 2011, and July 2012. Not currently an MVP.

MCTS

Image to show

Month List

Page List