XSLT ignore duplicate elements in single node at a

2019-08-27 16:19发布

I think my previous question was not clear so I am describing the situtation again.

Thanks for your help on this. I tried this but could not resolve my problem. I think I need to provide more insight into my issue.

    <TXLife>
        <TXLifeResponse>
            <Coverage>
                <LifeParticipant id="Party_040_01">
                    <ParticipantName>Sam</ParticipantName>
                    <LifeParticipantRoleCode tc="1">Primary Insured</LifeParticipantRoleCode>
                    <RateDecision>Rating C 100%</RateDecision>
                </LifeParticipant>
            </Coverage>
            <Coverage>
                <LifeParticipant id="Party_040_02">
                    <ParticipantName>Renny</ParticipantName>
                    <LifeParticipantRoleCode tc="2">Additional Insured</LifeParticipantRoleCode>
                    <RateDecision>Rating B 200%</RateDecision>
                </LifeParticipant>
            </Coverage>
            <Coverage>
                <LifeParticipant id="Party_040_01">
                    <ParticipantName>Sam</ParticipantName>
                    <LifeParticipantRoleCode tc="1">Primary Insured</LifeParticipantRoleCode>
                    <RateDecision>Rating D 700%</RateDecision>
                </LifeParticipant>
            </Coverage>
        </TXLifeResponse>
        <TXLifeResponse>
            <Coverage>
                <LifeParticipant id="Party_040_01">
                    <ParticipantName>Marry</ParticipantName>
                    <LifeParticipantRoleCode tc="1">Primary Insured</LifeParticipantRoleCode>
                    <RateDecision>Rating C 100%</RateDecision>
                </LifeParticipant>
            </Coverage>
            <Coverage>
                <LifeParticipant id="Party_040_03">
                    <ParticipantName>Sherry</ParticipantName>
                    <LifeParticipantRoleCode tc="2">Primary Insured</LifeParticipantRoleCode>
                    <RateDecision>Rating H 300%</RateDecision>
                </LifeParticipant>
            </Coverage>
            <Coverage>
                <LifeParticipant id="Party_040_01">
                    <ParticipantName>Marry</ParticipantName>
                    <LifeParticipantRoleCode tc="1">Primary Insured</LifeParticipantRoleCode>
                    <RateDecision>Rating A 50%</RateDecision>
                </LifeParticipant>
            </Coverage>
        </TXLifeResponse>
    </TXLife>

I need to find the RateDecision information by LifeParticipantRoleCode from multiple Coverage elements within TXLifeResponse at a time. And repeat the same for second TXLifeResponse and so on.

    Meaning I need to generate output like

    <TXLife>
        <TXLifeResponse>
            <RateDecision>Sam Rating C 100%, Rating D 700%</RateDecision>
            <RateDecision>Renny Rating B 200%</RateDecision>
        </TXLifeResponse>
        <TXLifeResponse>
            <RateDecision>Marry Rating C 100%, Rating A 50%</RateDecision>
            <RateDecision>Sherry Rating H 300%</RateDecision>
        </TXLifeResponse>
    </TXLife>

I don't want to generate two elements for Sam. I want to combine Sam's rating information from two different Coverage elements under single TXLifeResponse node and display it and then repeat the same process for second TXLifeResponse node.

I hope, I am able to clarify my question. Any help is appreciated.

I tried to implement the below logic and its still not working. Please assist.

<xsl:key name="LifeParticipant-by-LifeParticipantRoleCode" match="LifeParticipant" use="LifeParticipantRoleCode[@tc = '1' or @tc = '2' or @tc = '3' or @tc = '4' or @tc = '5' or @tc = '6']" />

<xsl:apply-templates select="Life/Coverage/LifeParticipant[generate-id() = generate-id(key('LifeParticipant-by-LifeParticipantRoleCode', LifeParticipantRoleCode/@tc)[1])]" />

<xsl:template match="LifeParticipant">
    <!-- Business Logic -->
</xsl:template>

标签: xslt
2条回答
爷、活的狠高调
2楼-- · 2019-08-27 16:51

Removing duplicates (in XSLT 1.0) is best handled through a technique known as Muenchian grouping.

The variation required here is to include the id of the parent node in the key. Here's an example of implementation:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="k" match="Coverage" use="concat(LifeParticipant/@id, '|', generate-id(..))"/>

<xsl:template match="/TXLife">
    <root>
        <xsl:apply-templates select="TXLifeResponse"/>
    </root>
</xsl:template>

<xsl:template match="TXLifeResponse">
    <group>
        <xsl:apply-templates select="Coverage[count(. | key('k', concat(LifeParticipant/@id, '|', generate-id(..)))[1]) = 1]"/>
    </group>
</xsl:template>

<xsl:template match="Coverage">
    <item>
        <xsl:value-of select="LifeParticipant"/>
    </item>
</xsl:template>

</xsl:stylesheet>

Applied to the given example input, the result will be:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <group>
      <item>tom</item>
      <item>sam</item>
   </group>
   <group>
      <item>tom</item>
      <item>jerry</item>
   </group>
</root>

I didn't see anything concerning "multiple files" here.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-08-27 17:10

I don't have a environment that could test this so only sudo code and not 100% sure it will work but what I would attempt with an issue like this is

Template Match at TXLifeResponse level
   for each coverage/LifeParticipant
     xsl:if test="not(preceding-sibling::LifeParticipant[@id=current()/@id])
       set variable (paramContext) to be current()    
       xslt:value-of setting value using a call to custom function (func1) passing paramContext, @id  and an empty string 
     end if
   end loop
end template

Then the function would use recursion something like the below

 if test="(paramContext/following-sibling::LifeParticipant[@id=paramID])
    set variable newContext = paramContext/following-sibling::LifeParticipant[@id=paramID]
    set variable concatstring = paramString concatenated with delimiter and RateDecision
    call func1 (recursivly) passing NewContext, paramID, concatString
  end if
end loop

Not sure if the context stuff will work but need to do something here otherwise the function will change the context in the outer section.

查看更多
登录 后发表回答