Xsl: How can I Group and sort based on sum?

前端 未结 1 1505
无人及你
无人及你 2021-01-21 21:01

I have the below xml

 
  
  

        
相关标签:
1条回答
  • 2021-01-21 21:39

    Something like this (I have re-constructing your code, as it was missing quite a lot):

    This XSLT transformation:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
     <xsl:param name="pSortBy" select="'Pass'"/>
    
     <xsl:key name="kResultByOwner" match="Result"
      use="@Owner"/>
    
        <xsl:template match="/">
            <table>
                <xsl:for-each select=
                "ResultCollection/Result
                     [generate-id(.) 
                     = 
                      generate-id(key('kResultByOwner', @Owner)[1])
                      ]">
                     <xsl:sort data-type="number" select=
                    "sum(key('kResultByOwner', @Owner)
                                   /@*[name()=$pSortBy])"/> 
    
                    <xsl:variable name="totFailures" select=
                    "sum(/ResultCollection/Result
                              [@Owner=current()/@Owner]
                                  /@Fail
                   )" />
                    <xsl:variable name="totPass" select=
                    "sum(/ResultCollection/Result
                               [@Owner=current()/@Owner]
                                  /@Pass
                   )" />
    
                    <xsl:variable name="total" select=
                       "$totPass+$totFailures" />
                    <tr>
                        <td>
                            <xsl:value-of select="current()/@Owner"/>
                        </td>
                        <td>
                            <xsl:value-of select="$total"/>
                        </td>
                        <td>
                            <xsl:value-of select="$totPass"/>
                        </td>
                        <td>
                            <xsl:value-of select="$totFailures"/>
                        </td>
                    </tr>
                </xsl:for-each>
            </table>
        </xsl:template>
    </xsl:stylesheet>
    

    when applied on the originally provided XML document:

    <ResultCollection>
        <Result Id="551550" Pass="23" Fail="0" Owner="Dong"/>
        <Result Id="551565" Pass="4" Fail="3" Owner="Dong"/>
        <Result Id="551567" Pass="61" Fail="0" Owner="Mei"/>
        <Result Id="551580" Pass="10" Fail="1" Owner="Dong"/>
        <Result Id="551580" Pass="0" Fail="4" Owner="Sen"/>
        <Result Id="551548" Pass="1" Fail="12" Owner="Sen"/>
    </ResultCollection>
    

    produces the wanted result):

    Sen        17    1  16
    Dong       41   37   4
    Mei        61   61   0
    
    

    Do note the following:

    1. The summation of the values of the @Pass or the @Fail attribute for the elements that belong only to the current group (the use of the key() function).

    2. The use of the <xsl:sort .../> instruction to sort by the required sums.

    3. The use of a global parameter named pSortBy, which contains the name of the attribute on the sums of which to sort.

    4. The use of the XSLT function current()

    0 讨论(0)
提交回复
热议问题