2009-04-17 3 views
2

У меня есть ниже XMLXsl: Как я могу группировать и сортировать по сумме?

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

И у меня есть XSL, который генерирует ниже резюме

Owner Total Pass Fail 
Dong 41 37 4 
Mei  61 61 0 
Sen  17 1 16 

Как сортировать этот результат, основанный на перевале или неудачу?

Мой XSL выглядит следующим образом

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:key name="FeatureOwner" match="Result" use="@Owner" /> 
    <xsl:template match="/"> 
     <html> 
     <head> 
      <title>Result Summary</title> 
     </head> 
     <body> 
       <table> 
        <tr> 
        <td> 
         <b>Owner</b></td> 
        <td> 
         <b>Total</b> 
        </td> 
        <td> 
         <b>Pass</b> 
        </td> 
        <td> 
         <b>Fail</b> 
        </td> 
        </tr> 
        <xsl:for-each select="ResultCollection/Result[generate-id(.) = generate-id(key('FeatureOwner', @Owner)[1])]"> 
        <xsl:variable name="varFeatureOwner"> 
         <xsl:value-of select="@Owner" /> 
        </xsl:variable> 
        <xsl:variable name="totFailures" select="sum(//ResultCollection/Result[@Owner=$varFeatureOwner]/@Fail)" /> 
        <xsl:variable name="totPass" select="sum(//ResultCollection/Result[@Owner=$varFeatureOwner]/@Pass)" /> 
        <xsl:variable name="total" select="$totPass+$totFailures" /> 
        <tr> 
         <td> 
          <xsl:value-of select="$varFeatureOwner"/> 
         </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> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 
+1

кода является весьма неполным. Пожалуйста, предоставьте полный, но минимально возможный рабочий код. –

ответ

2

Что-то вроде этого (я вновь строящейся код, так как он отсутствовал довольно много):

Этот XSLT преобразование:

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

при нанесении на поставляемом XML документе:

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

производит желаемый результат):

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

Вы обратит внимание на следующем:

  1. Суммирование от значений @Pass или атрибут @Fail для элементов, принадлежащих только текущей группе (использование функции key()).

  2. Использование инструкции <xsl:sort .../> для сортировки по требуемым суммам.

  3. Использование глобального параметра с именем pSortBy, который содержит имя атрибута на суммы, которые нужно сортировать.

  4. Использование функции XSLT current()

Смежные вопросы