2013-03-17 6 views
-1

Я пытаюсь использовать XSLT 2.0, чтобы суммировать все индивидуальные продажи [VOL] для продукта [Виджеты] для каждого года/годаQtr, сгруппированные по их салесте, отделу. Там может быть несколько типов продуктов, я оставил его как один тип здесь, чтобы попытаться упростить код.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's имеют ID 1, когда половина из них' Q2'. Это ошибка? Результат вашего примера также не показывает, как вы хотите представлять отдельных продавцов. – JLRishe

+0

Привет, да. я просто скопировал вставку, чтобы сделать примеры, извините. Я бы ожидал, что идентификатор yearmonth для yearqtr = 1 будет 1, 2 или 3 – leejkennedy

ответ

0

ли вам действительно нужно использовать группировку здесь? Если вы можете с уверенностью предположить, что в течение года всегда 4 квартала, вы можете просто написать сумму, чтобы суммировать все объемы виджета за данный квартал и год, например (где $ 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.

EDIT: Если у вас несколько лет, то предполагается, что вы все еще хотел их на отдельные столбцы, вы могли бы сделать группировку так:

<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

Привет, Тим C, и спасибо.как я могу отредактировать это, чтобы справиться с более чем одним годом? скажем, у меня был и 2012 год ... – leejkennedy

+0

, чтобы уточнить, возможно, что значения производительности могут включать предыдущий год, и я хотел бы показать, где это возможно. Я бы отредактировал код заголовка следующим образом: leejkennedy

+0

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

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