2

我有一个 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, ValueMappingfunctoid 与脚本 functoid (内联 C#)结合使用以在输入之间进行选择(如果条件成立),但没有给我正确的输出。

图片:http://i68.tinypic.com/2dj5d2c.jpg

通过这种安排(如图所示)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元素一直被忽略。

有人可以帮我吗?

4

1 回答 1

1

您应该能够使用循环 functoid 和几个逻辑 functoid 来做到这一点。将ITLoop1SACLoop2作为输入连接到循环 functoid,并将其输出到目标重复节点 ( MeasurementItems)。然后喜欢SAC05SAC15前往正确的目的地。最后,将一些Equalsfunctoids添加到地图中,SAC1作为输入,'A'作为第二个参数,并输出到MeasurementItems. 为两个元素添加相同的 functoid SAC1,并添加另一个C用作第二个输入的集合。有关更多信息,请参阅文档

如果您想在 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>
于 2016-01-18T14:16:04.623 回答