Looping over a scripting functoid in BizTalk

2019-08-27 08:46发布

I've got a list of string values like '123','456','789' and so on. This list can be very long with a few thousand items. So I have to split it in blocks of max. 750 items.
One idea is to write an own functoid which split in and returns a loopable list. Maybe it is a little bit easier and i could do it direcly in a scripting functoid. But I get the message

`error btm1090: The "Looping" functoid has place holders. Replace these with appropriate links or constants.`



So I don't think that this is possible. Is there a possibility to do it in a Scripting functoid or do I need my own functoid?

I need the splitted values on the one hand to create multiple results lines (by looping) but also the value itself in each line.

BizTalk Map

Thanks in advance.

2条回答
疯言疯语
2楼-- · 2019-08-27 09:33

Using Inline XSLT Call Template in Scripting functoids you could do something like this.

Functoid 1 (stand-alone):

<xsl:template name="SplitValues">
  <xsl:param name="value" />

  <xsl:variable name="part" select="substring-before($value, ',')" />

  <xsl:if test="$part != ''">
    <v><xsl:value-of select="$part" /></v>

    <xsl:call-template name="SplitValues">
      <xsl:with-param name="value" select="substring-after($value, ',')" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>

Functoid 2:

  <xsl:variable name="split">
    <xsl:call-template name="SplitValues">
      <xsl:with-param name="value" select="$value" />
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="set" select="msxsl:node-set($split)" />
  <xsl:variable name="size" select="750" />

  <xsl:for-each select="$set/v[position() mod $size = 1]">
    <xsl:variable name="start" select="(position() - 1) * $size + 1" />

    <LineValue>
      <xsl:value-of select="text()" />

      <xsl:for-each select="$set/v[position() &gt; $start and position() &lt; $start + $size]">
        <xsl:text>,</xsl:text>
        <xsl:value-of select="text()" />
      </xsl:for-each>
    </LineValue>
  </xsl:for-each>
</xsl:template>

Input[0]: the '123','456','789' node

查看更多
干净又极端
3楼-- · 2019-08-27 09:39

I would use a different approach. Instead of trying to do a restricted loop in Xsl, which is hard, I would generate all the Xml in a C# function, which is pretty easy.

Step 1, write some C# that create the Xml output you need:

<LineValue>'1','2','3',...,'749','750'</LineValue>
<LineValue>'751','752','753',...,'1499','1500'</LineValue>
<LineValue>'1501','1502','1503',...,'2249','2250'</LineValue>

An External Assembly is generally preferred but inline works just as well. But, it really doesn't matter, just return this Xml as a string.

Step 2, the only 'trick' you need is to pass the C# output through a Xslt Template so it's treated as Xml, not String content.

<xsl:template name="MyXsltConcatTemplate">
     <xsl:param name="param1" />
     <xsl:element name="field">
          <xsl:value-of select="$param1" disable-output-escaping="yes" />
     </xsl:element>
</xsl:template>

disable-output-escaping="yes" is what makes this work.

查看更多
登录 后发表回答