XSLT一次忽略单个节点中的重复元素

时间:2015-11-19 01:40:04

标签: xslt

我认为我之前的问题并不清楚,所以我再次描述了这个问题。

感谢您的帮助。我试过这个,但无法解决我的问题。我想我需要更深入地了解我的问题。

    <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>

我需要一次从TXLifeResponse中的多个Coverage元素中找到LifeParticipantRoleCode的RateDecision信息。并对第二个TXLifeResponse重复相同的操作,等等。

    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>

我不想为Sam生成两个元素。我想在单个TXLifeResponse节点下组合来自两个不同Coverage元素的Sam评级信息并显示它,然后为第二个TXLifeResponse节点重复相同的过程。

我希望,我能够澄清我的问题。任何帮助表示赞赏。

我试图实现以下逻辑,但它仍无效。请协助。

<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>

2 个答案:

答案 0 :(得分:2)

删除重复项(在XSLT 1.0中)最好通过称为Muenchian grouping的技术来处理。

此处所需的变体是在密钥中包含父节点的id。这是一个实施的例子:

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>

应用于给定的示例输入,结果将为:

<?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>

我没有看到任何关于&#34;多个文件&#34;这里。

答案 1 :(得分:0)

我没有一个可以测试这个环境的环境,所以只有sudo代码,而不是100%确定它会起作用,但我会尝试这样的问题

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

然后该函数将使用类似下面的递归

 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

不确定上下文内容是否有效但需要在此处执行某些操作,否则该函数将更改外部部分中的上下文。