如何使用BizTalk映射器将2个不同的节点映射到重复节点

时间:2012-09-04 15:07:57

标签: xslt biztalk biztalk-2010 biztalk-mapper

我有这个架构:

<Root>
  <Customers>
    <Customer>
      <ID>123</ID>
      <Name>John</Name>
    </Customer>
  </Customers>
  <Order>
    <ID>ABC</ID>
    <Title>Boat</Title>
  </Order>
</Root>

我需要将两个不同的记录映射到一个重复记录中,如下所示:

<Root>
  <Data>
    <ID>123</ID>
    <Text>John</Text>
  </Data>
  <Data>
    <ID>ABC</ID>
    <Text>Boat</Text>
  </Data>
</Root>

我尝试创建两个表循环(一个用于Customer,一个用于Order)并且得到:

<Root>
  <Data>
    <ID>ABC</ID>
    <Text>Boat</Text>
  </Data>
</Root>

试了一个用两行循环的表,并得到了相同的结果。 (也尝试使用门控选项来检查是否存在差异)

实际上模式很大,地图非常复杂(不是由我构建的),有很多fun​​ctoid和许多电线。所以我想避免创建一个自定义的XSL,这对于这个任务来说会更容易,但是更难维护。这是我需要改变的唯一部分。

有人吗? 感谢。

3 个答案:

答案 0 :(得分:3)

对于复杂的映射,使用自定义XSLT几乎总是比我们在BizTalk映射中经常发现的蜘蛛网更简单,更易于维护。但是,如您所述,您需要避免重新编码整个地图,因为您只更改了一小部分。

您应该能够在Scripting Functoid中使用“内联XSLT调用模板”脚本类型来组合最佳的BizTalk映射和自定义XSLT。

根据Sean B. Durkin的回答,您将需要设置2个呼叫模板functoid,第一个连接到您的输出'Data'节点

<xsl:template name="DataTemplate">
    <xsl:apply-templates select="//*[local-name()='Customer']|//*[local-name()='Order']" />
</xsl:template>

您的第二个呼叫模板会将相关数据输出到当前输出“数据”节点。请注意,第二个Functoid不需要连接到输出文档中的任何节点。

<xsl:template match="*[local-name()='Customer']|*[local-name()='Order']">
    <xsl:element name="Data">
      <xsl:element name="ID">
          <xsl:value-of select="*[local-name()='ID']"/>
      </xsl:element>
      <xsl:element name="Text">
          <xsl:value-of select="*[local-name()='Name']|*[local-name()='Title']" />
      </xsl:element>
    </xsl:element>
</xsl:template>

答案 1 :(得分:2)

这里不需要使用XSLT。只需在地图上拖动一个循环functoid即可。将Customer和Order记录连接为functoid的输入(是的,您可以有多个输入)。将functoid的输出连接到Data记录。然后直接连接您的字段(ID - &gt; ID,名称 - &gt;文字)。这将有效。

循环functoid的单个输入记录不必重复记录。通过将多个输入连接到functoid,您将循环遍历实例集合。

答案 2 :(得分:1)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
 <Root>
   <xsl:apply-templates select="*/Customers/Customer|*/Order"/>
 </Root>
</xsl:template>

<xsl:template match="Customer|Order">
 <Data>
   <ID><xsl:value-of select="ID" /></ID>
   <Text><xsl:value-of select="Name|Title" /></Text>
 </Data>
</xsl:template>

</xsl:stylesheet>