我有一个 EDI 810 文件,我必须从其中有条件地映射来自两个不同重复SAC
节点的某些值,这些重复节点在文档的不同位置多次出现。请注意,与节点SAC_2
相比,它发生在较低级别。SAC_3
源文档的示例片段如下所示:
<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
(to Amount
) 和SAC15
(to Description
) 元素的值,IFSAC_2/SAC01
具有值"C"
or "A"
。从 中SAC_3
,我需要映射SAC05
(to Amount
) 和SAC15
(to Description
) 元素的值,IFSAC_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
元素一直被忽略。
有人可以帮我吗?