BizTalk 2010 条件映射问题(从两个不同的重复源节点到同一目标节点)

BizTalk 2010 Conditional Mapping Issue (from two different recurring source nodes to same destination node)

我有一个 EDI 810 文件,我必须从中有条件地映射来自两个不同重复 SAC 节点的某些值,这些节点在文档的不同位置多次出现。请注意,与 SAC_3 节点相比,SAC_2 出现在较低级别。源文档的示例片段如下所示:

<ns1:IT1Loop1>
  <ns1:SLNLoop1>
    <ns1:SAC_2>
      <SAC01>C</ID>
      <SAC05>3443</Name>
      <SAC15>Service A</ID>
    </ns1:SAC_2>
  </ns1:SLNLoop1>
  <ns1:SLNLoop1>
    <ns1:SAC_2>
      <SAC01>C</ID>
      <SAC05>120</Name>
      <SAC15>Service B</ID>
    </ns1:SAC_2>
  </ns1:SLNLoop1>
  <ns1:SLNLoop1>
    <ns1:SAC_2>
      <SAC01>A</ID>
      <SAC05>243</Name>
      <SAC15>Service D</ID>
    </ns1:SAC_2>
  </ns1:SLNLoop1>
</ns1:IT1Loop1>
<ns1:IT1Loop1>
  <ns1:SLNLoop1>
    <ns1:SAC_2>
      <SAC01>A</ID>
      <SAC05>567</Name>
      <SAC15>Service C</ID>
    </ns1:SAC_2>
  </ns1:SLNLoop1>
  <ns1:SLNLoop1>
    <ns1:SAC_2>
      <SAC01>F</ID>
      <SAC05>4558</Name>
      <SAC15>Service M</ID>
    </ns1:SAC_2>
  </ns1:SLNLoop1>
</ns1:IT1Loop1>
<ns1:SACLoop2>
  <ns1:SAC_3>
    <SAC01>A</ID>
    <SAC05>-1234</Name>
    <SAC15>Adjustment</ID>
  </ns1:SAC_3>
</ns1:SACLoop2>
<ns1:SACLoop2>
  <ns1:SAC_3>
    <SAC01>D</ID>
    <SAC05>24567</Name>
    <SAC15>Balance Forward</ID>
  </ns1:SAC_3>
</ns1:SACLoop2>

条件如下: 从 SAC_2,我需要映射 SAC05(到 Amount)和 SAC15(到 Description)元素的值,IF SAC_2/SAC01 的值为 "C""A"。 从 SAC_3,我需要映射 SAC05(到 Amount)和 SAC15(到 Description)元素的值,IF SAC_3/SAC01 的值为 "C""A" AND SAC15 != "Balance Forward"。 因此,它应该生成与满足条件的这些段中的任何一个一样多的 "MeasureItems" 。 以下是样本输入的输出结果:

<Root>
  <HeaderItems>
  ...
  </HeaderItems>
  <MeasureItems>
    <Description>Service A</Description>
    <Amount>3443</Amount>
  </MeasureItems>
  <MeasureItems>
    <Description>Service B</Description>
    <Amount>120</Amount>
  </MeasureItems>
  <MeasureItems>
    <Description>Service D</Description>
    <Amount>243</Amount>
  </MeasureItems>
  <MeasureItems>
    <Description>Service C</Description>
    <Amount>567</Amount>
  </MeasureItems>
  <MeasureItems>
    <Description>Adjustment</Description>
    <Amount>-1234</Amount>
  </MeasureItems>
  <ReadItems>
  ...
  </ReadItems>
</Root>

没有办法仅通过单独的 functoid 轻松完成此操作,因此我尝试了 EqualToNotEqualToLogicalORValueMapping functoid 的组合使用脚本 functoid(内联 C#)在输入之间进行选择(如果条件成立),但没有给我正确的输出。

图片:

通过这种安排(如图所示)functoid,我总是会从 SAC_2 重复中正确映射所有内容,但它会完全忽略 SAC_3 元素。

并且使用内联 XSLT,它总是只从第一次出现的 SAC_2 片段映射到每个重复出现的 IT1Loop1 父片段。当然,它会再次完全忽略 SAC_3 元素。

这是我使用的内联 XSLT 代码的一个版本:

<xsl:element name = "Description">

  <xsl:choose>
    <xsl:when test=".//*[local-name()='SAC_2']/SAC01 = 'C' or .//*[local-name()='SAC_2']/SAC01 = 'A'">
      <xsl:value-of select = ".//*[local-name()='SAC_2']/SAC15[preceding-sibling::SAC01='C' or preceding-sibling::SAC01='A']"/>
    </xsl:when>
    <xsl:when test=".//*[local-name()='SAC_3']/SAC01 = 'C' and not(.//*[local-name()='SAC_3']/SAC15 = 'Balance Forward')">
      <xsl:value-of select = ".//*[local-name()='SAC_3']/SAC15[preceding-sibling::SAC01='C' or preceding-sibling::SAC01='A']"/>
    </xsl:when>
  </xsl:choose>

</xsl:element>

我猜 switch 语句和循环在 XSLT 中的工作方式与在其他语言中的工作方式不同。此外,我也单独通过内联 C# 尝试了相同的逻辑。它没有产生正确的结果。

我很确定应该有一种方法可以使用内联 XSLT 或其他一些自定义代码解决方案来执行此操作。

此外,我不明白为什么 SAC_3 元素总是被忽略。

有人可以帮我解决这个问题吗?

您应该能够使用循环 functoid 和几个逻辑 functoid 来完成此操作。将 ITLoop1SACLoop2 作为输入连接到循环 functoid,并将其输出到目标重复节点 (MeasurementItems)。然后点赞 SAC05SAC15 到正确的目的地。最后,向映射中添加一些Equals functoids,以SAC1作为输入,'A'作为第二个参数,输出到MeasurementItems。为两个 SAC1 元素和另一个使用 C 作为第二个输入的集合添加相同的 functoid。有关详细信息,请参阅 documentation

如果您想在 XSLT 中执行此操作,则必须生成整个 MeasurementItems 节点,这可能会或可能不会比它的价值更难(或者可能值得在XSLT)。您的模板看起来像这样:

<xsl:template match="//ns1:SAC_2[SAC01='A' or SAC01='C'] | //ns1:SAC_3[(SAC01 = 'A' or SAC01= 'C') and SAC15 != 'Balance Forward']" xmlns:ns1='REPLACE_WITH_REAL_NAMESPACE'>
  <Amount>
    <xsl:value-of select="SAC05" />  
  </Amount>
  <Description>
    <xsl:value-of select="SAC15" />  
  </Description>
</xsl:template>