2013-03-17 62 views
-1

我试图使用XSLT 2.0来总结每个Year/YearQtr的产品[Widgets]的所有单个销售人员[VOL],并按其销售部门进行分组。可能有多种产品类型,我只是将它留在了一种类型中,以试图简化代码。XSLT 2组和总和值

  1. 我已经成功地使用的,各领YearQtr值列表中某一年,但我不能工作,如何让显示为全年和YearQtr元素的不同列表SalesPerson/Performance的孩子。
  2. 我试过currentgroup(),但不能看到如何指定分组,以便我只能得到部门级别的总和,而不是每个SalesPerson。

我正在使用的XML是:

<salesteam id="Team1"> 
    <department id="dept1"> 
     <salespeople> 
      <salesperson id="98765"> 
       <performance> 
        <year id="2013"> 
         <yearqtr id="1"> 
          <yearMonth id="1"> 
           <products> 
            <widgets> 
             <vol>5</vol> 
             <val>50000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
          <yearMonth id="2"> 
           <products> 
            <widgets> 
             <vol>10</vol> 
             <val>100000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
          <yearMonth id="3"> 
           <products> 
            <widgets> 
             <vol>15</vol> 
             <val>150000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
         </yearqtr> 
         <yearqtr id="2"> 
          <yearMonth id="4"> 
           <products> 
            <widgets> 
             <vol>20</vol> 
             <val>200000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
          <yearMonth id="5"> 
           <products> 
            <widgets> 
             <vol>25</vol> 
             <val>250000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
          <yearMonth id="6"> 
           <products> 
            <widgets> 
             <vol>30</vol> 
             <val>300000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
         </yearqtr> 
        </year> 
       </performance> 
      </salesperson> 
      <salesperson id="12345"> 
       <performance> 
        <year id="2013"> 
         <yearqtr id="1"> 
          <yearMonth id="1"> 
           <products> 
            <widgets> 
             <vol>5</vol> 
             <val>50000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
          <yearMonth id="2"> 
           <products> 
            <widgets> 
             <vol>10</vol> 
             <val>100000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
          <yearMonth id="3"> 
           <products> 
            <widgets> 
             <vol>15</vol> 
             <val>150000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
         </yearqtr> 
         <yearqtr id="2"> 
          <yearMonth id="4"> 
           <products> 
            <widgets> 
             <vol>20</vol> 
             <val>200000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
          <yearMonth id="5"> 
           <products> 
            <widgets> 
             <vol>25</vol> 
             <val>250000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
          <yearMonth id="6"> 
           <products> 
            <widgets> 
             <vol>30</vol> 
             <val>300000</val> 
            </widgets> 
           </products> 
          </yearMonth> 
         </yearqtr> 
        </year> 
       </performance> 
      </salesperson> 
     </salespeople> 
    </department> 
</salesteam> 

我想达到什么是

<table> 
<tbody> 
<tr> 
<th>2013Q1</th> 
<th>2013Q2</th> 
<th>2013Q3</th> 
<th>2013Q4</th> 
</tr> 
<tr> 
<td>30</td> 
<td>75</td> 
<td>0</td> 
<td>0</td> 
</tr> 
</tbody> 
</table> 
+0

我不太明白为什么你所有的'yearqtr'都有ID 1,其中一半是'Q2'。这是一个错误吗?您的示例输出也似乎并不能说明您想如何代表独立的销售人员。 – JLRishe 2013-03-17 12:57:04

+0

嗨,是的。我刚刚复制粘贴的例子,对不起。我期望yearqtr = 1的yearmonth id为1,2或3 – leejkennedy 2013-03-17 13:17:47

回答

0

你真的需要使用此分组?如果你可以安全地假设一年总共有四个季度,那么你可以有一个总和声明来总结给定季度和年份的所有小部件的总量,就像这样(其中$ year是一年中的参数,而$ QTR拿着季度)

<xsl:value-of select="sum(//year[@id=$year]/yearqtr[@id=$qtr]/yearMonth/products/widgets/vol)" /> 

你可以只把这个命名模板,用QTR作为参数,并将其命名为四次

<xsl:call-template name="sum"><xsl:with-param name="qtr" select="1" /></xsl:call-template> 
<xsl:call-template name="sum"><xsl:with-param name="qtr" select="2" /></xsl:call-template> 
<xsl:call-template name="sum"><xsl:with-param name="qtr" select="3" /></xsl:call-template> 
<xsl:call-template name="sum"><xsl:with-param name="qtr" select="4" /></xsl:call-template> 

这可能是稍微干净,更有效地使用密钥来查找特定年份和季度的小部件。

<xsl:key name="quarters" match="yearqtr" use="concat(../@id, '|', @id)"/> 

那么你的总和成为该

<xsl:value-of 
    select="sum(key('quarters', concat($year, '|', $qtr))/yearMonth/products/widgets/vol)"/> 

下面是在这种情况下,全XSLT:

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

    <xsl:key name="quarters" match="yearqtr" use="concat(../@id, '|', @id)"/> 

    <xsl:param name="year" select="2013"/> 

    <xsl:template match="/*"> 
     <table> 
     <tbody> 
      <tr> 
       <th><xsl:value-of select="$year"/>Q1</th> 
       <th><xsl:value-of select="$year"/>Q2</th> 
       <th><xsl:value-of select="$year"/>Q3</th> 
       <th><xsl:value-of select="$year"/>Q4</th> 
      </tr> 
      <tr> 
       <xsl:call-template name="sum"><xsl:with-param name="qtr" select="1" /></xsl:call-template> 
       <xsl:call-template name="sum"><xsl:with-param name="qtr" select="2" /></xsl:call-template> 
       <xsl:call-template name="sum"><xsl:with-param name="qtr" select="3" /></xsl:call-template> 
       <xsl:call-template name="sum"><xsl:with-param name="qtr" select="4" /></xsl:call-template> 
      </tr> 
     </tbody> 
     </table> 
    </xsl:template> 

    <xsl:template name="sum"> 
     <xsl:param name="qtr"/> 
     <td> 
     <xsl:value-of select="sum(key('quarters', concat($year, '|', $qtr))/yearMonth/products/widgets/vol)"/> 
     </td> 
    </xsl:template> 
</xsl:stylesheet> 

如果你确实想使用,虽然分组,这里是你会怎么做它在XSLT2.0中

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:param name="year" select="2013"/> 

    <xsl:template match="/*"> 
     <table> 
     <tbody> 
      <tr> 
       <xsl:for-each-group select="//year[@id=$year]/yearqtr" group-by="@id"> 
        <td><xsl:value-of select="concat($year, 'Q', current-grouping-key())" /></td> 
       </xsl:for-each-group> 
      </tr> 
      <tr> 
       <xsl:for-each-group select="//year[@id=$year]/yearqtr" group-by="@id"> 
        <td><xsl:value-of select="sum(current-group()/yearMonth/products/widgets/vol)"/></td> 
       </xsl:for-each-group> 
      </tr> 
     </tbody> 
     </table> 
    </xsl:template> 
</xsl:stylesheet> 

这只会显示虽然存在的宿舍,所以如果没有yearqtr元素为季度4,例如,只显示宿舍1到3。

编辑:如果你有多个年,那么假设你仍然希望他们在单独的列,你会做像这样的分组:

<xsl:for-each-group select="//yearqtr" group-by="concat(../@id, 'Q', @id)"> 

下面是在这种情况下,全XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/*"> 
     <table> 
     <tbody> 
      <tr> 
       <xsl:for-each-group select="//yearqtr" group-by="concat(../@id, 'Q', @id)"> 
        <td><xsl:value-of select="current-grouping-key()" /></td> 
       </xsl:for-each-group> 
      </tr> 
      <tr> 
       <xsl:for-each-group select="//yearqtr" group-by="concat(../@id, 'Q', @id)"> 
        <td><xsl:value-of select="sum(current-group()/yearMonth/products/widgets/vol)"/></td> 
       </xsl:for-each-group> 
      </tr> 
     </tbody> 
     </table> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Hi Tim C,谢谢。我怎么能编辑这个应付一年以上?说我有2012年以及... – leejkennedy 2013-03-17 17:20:25

+0

澄清,有可能性能值可能包括前一年,我想在两个可能的地方显示。我会编辑标题代码,如下所示:<! - language:lang-xml - > leejkennedy 2013-03-17 17:25:50

+0

I'我已经编辑了我的答案,以展示如何应对多年。 – 2013-03-17 17:38:09