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 轻松完成此操作,因此我尝试了 EqualTo
、NotEqualTo
、LogicalOR
、ValueMapping
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 来完成此操作。将 ITLoop1
和 SACLoop2
作为输入连接到循环 functoid,并将其输出到目标重复节点 (MeasurementItems
)。然后点赞 SAC05
和 SAC15
到正确的目的地。最后,向映射中添加一些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>
我有一个 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 轻松完成此操作,因此我尝试了 EqualTo
、NotEqualTo
、LogicalOR
、ValueMapping
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 来完成此操作。将 ITLoop1
和 SACLoop2
作为输入连接到循环 functoid,并将其输出到目标重复节点 (MeasurementItems
)。然后点赞 SAC05
和 SAC15
到正确的目的地。最后,向映射中添加一些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>