-1

我正在尝试使用 XSLT 2.0 来汇总每个 Year/YearQtr 的产品 [Widgets] 的所有个人销售人员 [VOL],按他们的销售团队、部门分组。可能有多种产品类型,我在这里只保留一种类型来尝试简化代码。

  1. 我已经设法使用 for-each 来获取特定年份中 YearQtr 值的列表,但我无法弄清楚如何获取作为 SalesPerson/Performance 的子项出现的所有 Year 和 YearQtr 元素的不同列表.
  2. 我已经尝试过 currentgroup(),但看不到如何指定分组,以便我只能获得部门级别的总和,而不是每个销售人员的总和。

我正在使用的 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>
4

1 回答 1

0

你真的需要在这里使用分组吗?如果您可以安全地假设一年中总是有 4 个季度,那么您可以只使用一个 sum 语句来汇总给定季度和年份的所有小部件数量,就像这样(其中 $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>
于 2013-03-17T17:07:09.293 回答