我有一个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
(到Amount
)和SAC15
(到Description
)元素的值,IF {{1} }具有值SAC_2/SAC01
或"C"
。
从"A"
开始,我需要映射SAC_3
(到SAC05
)和Amount
(到SAC15
)元素的值,IF {{1} }具有值Description
或SAC_3/SAC01
和"C"
。
因此,它应该生成尽可能多的"A"
,因为这些段中的任何一个都符合标准。
以下是示例输入的输出结果:
SAC15 != "Balance Forward"
单独使用functoid无法轻松完成此操作,因此我尝试了"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>
,EqualTo
,NotEqualTo
functoid的组合以及脚本functoid(内联C#)在输入之间进行选择(如果条件保持为真),但没有给我正确的输出。
通过这种排列(如图所示)functoid,我总是可以从LogicalOR
重复中正确地映射所有内容,但它会完全忽略ValueMapping
个元素。
对于内联XSLT,它始终只映射来自每个定期SAC_2
父级的SAC_3
段的第一次出现。当然,它会完全忽略SAC_2
元素。
以下是我使用的内联XSLT代码的一个版本:
IT1Loop1
我猜测switch语句和循环在XSLT中的工作方式与在其他语言中的工作方式不同。另外,我也通过内联C#尝试了相同的逻辑。它没有产生正确的结果。
我非常确定应该有一种方法可以使用内联XSLT或其他一些自定义代码解决方案。
此外,我不明白为什么SAC_3
元素会被忽略。
有人可以帮帮我吗?
答案 0 :(得分:1)
你应该能够通过循环functoid和几个逻辑functoid来做到这一点。将ITLoop1
和SACLoop2
作为输入连接到循环functoid,并将其输出到目标重复节点(MeasurementItems
)。然后将SAC05
和SAC15
添加到正确的目的地。最后,在地图中添加一些Equals
functoid,其中SAC1
作为输入,'A'作为第二个参数,并输出到MeasurementItems
。为两个SAC1
元素添加相同的functoid,使用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>