Xsl:如何根据总和进行分组和排序? [英] Xsl: How can I Group and sort based on sum?

查看:25
本文介绍了Xsl:如何根据总和进行分组和排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下 xml

 <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

所有者总通过失败董 41 37 4梅 61 61 0森 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="/"><头><title>结果摘要</title><身体><表格><tr><td><b>所有者</b></td><td><b>总计</b></td><td><b>通过</b></td><td><b>失败</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:变量><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></html></xsl:模板></xsl:stylesheet>

解决方案

类似这样的事情(我已经重新构建了你的代码,因为它缺失了很多):

这个 XSLT 转换:

<xsl:param name="pSortBy" select="'Pass'"/><xsl:key name="kResultByOwner" match="Result"使用="@所有者"/><xsl:template match="/"><表格><xsl:for-each select="结果集合/结果[生成-id(.)=生成 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]/@失败)"/><xsl:variable name="totPass" select="sum(/ResultCollection/Result[@Owner=current()/@Owner]/@经过)"/><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></xsl:模板></xsl:stylesheet>

应用于最初提供的 XML 文档时:

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

产生想要的结果):

<预>森 17 1 16董 41 37 4梅 61 61 0

请注意以下事项:

  1. 仅属于当前组的元素的 @Pass@Fail 属性值的总和(使用 key() 函数).

  2. 使用 <xsl:sort .../> 指令按所需的总和进行排序.

  3. 使用名为 pSortBy 的全局参数,其中包含要排序的总和的属性名称.

  4. XSLT函数的使用current()

I have the below 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>

And I have an xsl that generates the below summary

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

How can I sort this result based on Pass or Fail?

My xsl looks like this

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

解决方案

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

这篇关于Xsl:如何根据总和进行分组和排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆