在目标文档上创建可变数量的节点,而在源文档上没有相应的数据

发布于 2024-12-05 12:25:47 字数 843 浏览 1 评论 0原文

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

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

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

有没有办法使用 functoid 的某种组合来创建这些 节点?

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

I'm trying to map two documents witht the BizTalk Mapper and my target document should look like this:

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

The number of <filler> nodes that I should create is variable (from 0 to 9). It is basically the result of a calculation (based on some data provided in the source document).

Is there a way to create those <filler> nodes with some combination of functoids?

I tried to use the Table Looping functoid (created a table with only one column, the padding char '9') but doesn't really work because it creates as many <filler> nodes as rows are defined in the table, which is not what I want since the number of rows would have to be variable (again, based on a calculation).
What I currently do is pass the message (XmlDocument) to a C# method and then I programmatically append the <filler> nodes.
I'm hoping that there is a more "BizTalk-y" way of doing this with the Mapper.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最近可好 2024-12-12 12:25:47

我怀疑您必须通过更改 XSLT 来解决这个问题。

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

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

I suspect that you will have to solve this problem by altering the XSLT.

Add some logic to create as many filler nodes as the result of your calculation dictates - you could create a template which you call in a loop perhaps, which would append a new filler section.

Hope this points you in the right direction.

网白 2024-12-12 12:25:47

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

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

<一href="http://snippets.dzone.com/posts/show/930" rel="nofollow">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 <= $length"> 
<Filler>
    <Padding>999999</Padding>
</Filler>
</xsl:if> 

<!-- Call the ForLoop template recursively, incrementing i -->
<xsl:if test="$i <= $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>

As pointed out, XSLT can create nodes on the target document at will (I didn't know this and this was the key part).
Turns out that what I needed is a simple for-loop in XSLT. Once I realized this, a quick Google search yielded the following results:

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

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

Another thing worth noting is that (as pointed out by the first link), XSLT is a functional language, not procedural, so sometimes you do have to resort to using recursion or an extension.
This case is definitely one of those times since I couldn't use a careful selection of nodes using the select attribute on an xsl:for-each (since this filler data wasn't part of the source document).

Specifically, for this case, what I did was:

Add a Scripting functoid.
Add two inputs:

  • A constant with value "1" (this is the initial value of the i variable)
  • The length of the loop (number of times to repeat the body of the loop)

Paste the following XSLT template as an "Inline XSLT Call Template" script:

<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 <= $length"> 
<Filler>
    <Padding>999999</Padding>
</Filler>
</xsl:if> 

<!-- Call the ForLoop template recursively, incrementing i -->
<xsl:if test="$i <= $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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文