I have an EDI 810 file, from which I have to conditionally map certain values from two different repeating SAC
nodes, which occur multiple times in different spots in the document. Please note that the SAC_2
occurs at a lower level when compared to the SAC_3
node. A sample fragment of the source document looks like this:
<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>
Here are the conditions:
From the SAC_2
, I need to map the values of the SAC05
(to Amount
) and SAC15
(to Description
) elements, IF SAC_2/SAC01
has the values "C"
or "A"
.
From the SAC_3
, I need to map the values of the SAC05
(to Amount
) and SAC15
(to Description
) elements, IF SAC_3/SAC01
has the values "C"
or "A"
AND the SAC15 != "Balance Forward"
.
So it is supposed to generate as many "MeasureItems"
as there are any of these segments with criteria fulfilled.
Here is what the output should look like for the sample input:
<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>
There is no way to do this easily through only functoids alone so I have tried a combination of the EqualTo
, NotEqualTo
, LogicalOR
, ValueMapping
functoids along with the scripting functoid (inline C#) to choose between inputs (if conditions held true), but nothing gave me the correct output.
With this arrangement (shown in image) functoid I would always get everything mapped correctly from the SAC_2
repetitions but it would completely ignore the SAC_3
elements.
And with inline XSLT it would always map only from the first occurrence of SAC_2
segment, from each recurring IT1Loop1
parent. And, of course, it would completely ignore the SAC_3
elements again.
Here is one version of the inline XSLT code I used:
<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>
I'm guessing switch statements and loops don't work the same way in XSLT as they do in other languages. Also, I tried the same logic through inline C# alone too. It did not yield correct results.
I'm quite sure there should be a way to do this using inline XSLT or some other custom code solution.
Additionally, I don't understand why the SAC_3
elements keep getting ignored.
Could someone please help me with this?