2

我正在尝试使用 BizTalk Mapper 映射两个文档,我的目标文档应如下所示:

<root>
  <complexType>
     <property>example</property>
  </complexType>
  <filler>
     <padding>9999999</padding>
  </filler>
  <filler>
     <padding>9999999</padding>
  </filler>
  <filler>
     <padding>9999999</padding>
  </filler>
</root>

我应该创建的<filler>节点数是可变的(从 0 到 9)。它基本上是计算的结果(基于源文档中提供的一些数据)。

有没有办法<filler>用一些functoids组合来创建这些节点?

我尝试使用 Table Looping functoid(创建了一个只有一列的表,填充字符 '9')但并没有真正起作用,因为它创建的<filler>节点与表中定义的行一样多,这不是我想要的因为行数必须是可变的(同样,基于计算)。我目前所做的是将消息 (XmlDocument) 传递给 C# 方法,然后以编程方式附加<filler>节点。我希望 Mapper 有一种更“BizTalk-y”的方式来做到这一点。

4

2 回答 2

1

我怀疑您将不得不通过更改 XSLT 来解决这个问题。

添加一些逻辑以根据计算结果创建尽可能多的填充节点 - 您可以创建一个模板,您可能会在循环中调用该模板,这将附加一个新的填充部分。

希望这能为您指明正确的方向。

于 2011-09-21T09:47:01.597 回答
1

正如所指出的,XSLT 可以随意在目标文档上创建节点(我不知道这一点,这是关键部分)。事实证明,我需要的是 XSLT 中的一个简单的 for 循环。一旦我意识到这一点,快速的谷歌搜索产生了以下结果:

http://quomon.com/question-How-to-make-a-for-loop-in-xslt-not-for-each-809.aspx

http://snippets.dzone.com/posts/show/930

另一件值得注意的事情是(正如第一个链接所指出的),XSLT 是一种功能语言,而不是过程语言,因此有时您必须求助于使用递归或扩展。这种情况绝对是其中一种情况,因为我无法使用 xsl:for-each 上的 select 属性仔细选择节点(因为此填充数据不是源文档的一部分)。

具体来说,对于这种情况,我所做的是:

添加一个脚本functoid。添加两个输入:

  • 值为“1”的常量(这是 i 变量的初始值)
  • 循环的长度(循环主体的重复次数)

将以下 XSLT 模板粘贴为“内联 XSLT 调用模板”脚本:

<xsl:template name="ForLoop"> 
<xsl:param name="i" />      <!-- index counter, 1-based, will be incremented with every recursive call -->
<xsl:param name="length" /> <!-- exit loop when i >= length -->

<!-- Output the desired node(s) if we're still looping -->
<!-- The base case is when i > length (in that case, do nothing) -->
<xsl:if test="$i &lt;= $length"> 
<Filler>
    <Padding>999999</Padding>
</Filler>
</xsl:if> 

<!-- Call the ForLoop template recursively, incrementing i -->
<xsl:if test="$i &lt;= $length"> 
<xsl:call-template name="ForLoop"> 
<xsl:with-param name="i"> 
<xsl:value-of select="$i + 1"/> 
</xsl:with-param> 
<xsl:with-param name="length"> 
<xsl:value-of select="$length"/> 
</xsl:with-param> 
</xsl:call-template> 
</xsl:if> 
</xsl:template>
于 2011-09-21T18:01:39.257 回答