XSLT按日期透视数据

时间:2013-09-24 15:39:55

标签: xslt

我有一些XML记录按日期显示销售情况。我需要将此信息透视到一个表格中,该表格显示一周的销售额。

这是XML:

<?xml version="1.0"?>
 -<data>
   <report datetime="9/24/2013 10:27 AM"/>
   <reportnumber displayas="Report Number">7</reportnumber>
   <businessdate displayas="Business Date">08/19/2013 to 08/25/2013</businessdate>
   <businesssiteids displayas="Store">NEBO Enchiladas</businesssiteids>
   <colheaders>
    -<colheader day7="08/25/2013" day7name="Sunday" day6="08/24/2013" day6name="Saturday"    day5="08/23/2013" day5name="Friday" day4="08/22/2013" day4name="Thursday" day3="08/21/2013" day3name="Wednesday" day2="08/20/2013" day2name="Tuesday" day1="08/19/2013" day1name="Monday"/>
   </colheaders>
   <row ReportAmtDaily="0.000000" ListName="Closing Reading:" BusinessDate="2013-08-19T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="1"/>
   <row ReportAmtDaily="0.000000" ListName="Closing Reading:" BusinessDate="2013-08-21T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="2"/>
   <row ReportAmtDaily="0.000000" ListName="Closing Reading:" BusinessDate="2013-08-22T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="3"/>
   <row ReportAmtDaily="0.000000" ListName="Closing Reading:" BusinessDate="2013-08-23T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="4"/>
   <row ReportAmtDaily="0.000000" ListName=" - Opening Reading" BusinessDate="2013-08-19T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="5"/>
   <row ReportAmtDaily="0.000000" ListName=" - Opening Reading" BusinessDate="2013-08-21T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="6"/>
   <row ReportAmtDaily="0.000000" ListName=" - Opening Reading" BusinessDate="2013-08-22T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="7"/>
   <row ReportAmtDaily="0.000000" ListName=" - Opening Reading" BusinessDate="2013-08-23T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="8"/>
   <row ReportAmtDaily="3334.220000"  ListName="Gross Sales:" BusinessDate="2013-08-19T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="9"/>
   <row ReportAmtDaily="4187.620000" ListName="Gross Sales:" BusinessDate="2013-08-21T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="10"/>
   <row ReportAmtDaily="572.190000" ListName="Gross Sales:" BusinessDate="2013-08-22T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="11"/>
   <row ReportAmtDaily="10856.970000" ListName="Gross Sales:" BusinessDate="2013-08-23T00:00:00" BusinessSiteId="40E9E40D-5E7E-4EB3-99C6-8013CD31480D" linenumber="12"/>
</data>

我希望每个businesssiteid的输出看起来像这样:

------------------08/19/2013  08/20/20/2013 08/21/2013  08/22/2013  08/23/2013  08/24/2013 08/25/2013

Closing Reading:   0             0               0        0         0           0           0
-Opening Reading   0             0               0        0         0           0           0
Gross Sales        3334.22       0             4187.62    572.19    10856.97    0           0

我尝试在我的XSLT中使用键和变量,但没有任何方法返回,我认为这是正确的,因为我需要一个基于BusinessDate,ListName和BusinessSiteId组合的值。

此模板以非旋转格式返回数据。有人可以指出我正确的方向。

<xsl:template match="row">  
  <tr>
    <td>
      <div class="col1">
        <xsl:value-of select="@ListName"/>
      </div>
    </td>
    <td>
      <div class="col2">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col3">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col4">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col5">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col6">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col7">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col8">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col9">
        <!--<xsl:value-of select="@"/>-->
      </div>
    </td>
  </tr>      
<!--</xsl:if>-->    

XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" exclude-result-prefixes="msxsl"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <user:data xmlns:user="user">
<datamodel name="Sales.SDR">
 <editable value="false" />
  <fields>ListName,ReportQtyDaily</fields>
  <filters>
    <filter field="ReportNumber" value="7" />
  </filters>
  <totals />
  <sorting>
  </sorting>
  <grouping />
  <parameters>
    <parameter field="BusinessDate" prompt="true" />
    <parameter field="BusinessSiteIds" prompt="true" />
  </parameters>
  <reportheader headerfile="netsales1.xslt"/>
</datamodel>
<version>1.0</version>
<reportdescription>Filtered by: ReportNumber Parameters:
BusinessDate,BusinessSiteIds Fields Displayed: Line
Text</reportdescription>
<orientation value="horizontal" />
</user:data>
<xsl:output method="html" />
<xsl:key name="kListName" match="/data/row/@ListName" use="."/>
<xsl:template match="data">
<html>
  <head />
  <style type="text/css">div.col1{width:2.00in;left}div.col2{width:1.00in;right}div.col3{width:1.00in;right}div.col4{width:1.00in;right}div.col5{width:1.00in;right}div.col6{width:1.00in;right}div.col7{width:1.00in;right}div.col8{width:1.00in;right}div.col9{width:1.00in;right}</style>
  <body>
    <table class="report_header">
      <tr>
        <td class="title">Weekly SDR</td>
      </tr>
      <tr>
        <td>
          <table>
            <tr>
              <td />
              <td class="parameterlabel">Business Date:</td>
              <td>
                <xsl:value-of select="businessdate" />
              </td>
            </tr>
            <tr>
              <td />
              <td class="parameterlabel">Store:</td>
              <td>
                <xsl:value-of select="businesssiteids" />
              </td>
            </tr>
          </table>
        </td>
      </tr>
      <tr>
        <td />
        <td />
      </tr>
      <tr>
        <td>
          <table class="report_tabulardata">
            <thead class="report_tabulardata">
              <tr class="columnheader">
                <xsl:apply-templates select="colheaders/colheader" />
              </tr>                 
            </thead>
          </table>
        </td>
      </tr>
      <tr>
        <td>
          <table class="report_tabulardata">
            <xsl:apply-templates select="row" />
          </table>
        </td>
      </tr>
    </table>
  </body>
</html>

...other templates remove to make it easier to read      
<xsl:template match="row">
  <!--<xsl:for-each select="row[@ListName]">
  <xsl:variable name="desc" select="row[@ListName]"/>-->
  <tr>
    <td>
      <div class="col1" align="left">
        <xsl:value-of select="@ListName"/>
      </div>
    </td>
    <!--<xsl:for-each select="//@region[generate-id(.)= generate-id(key('b',.)[1])]">          
    </xsl:for-each>-->
    <td>
      <div class="col2" align="right">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col3" align="right">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col4" align="right">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col5" align="right">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col6" align="right">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col7" align="right">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col8" align="right">
        <xsl:value-of select="@ReportAmtDaily"/>
      </div>
    </td>
    <td>
      <div class="col9" align="right">
        <!--<xsl:value-of select="sum($thisGroup/@ReportAmtDaily)"/>-->        
      </div>
    </td>
  </tr>
<!--</xsl:for-each>-->
</xsl:template>  
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

这样的事情可能会起到作用:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:variable
    select="reverse(/data/colheaders/colheader/@*[not(local-name()[contains(.,'name')])])"
    name="days"/>
<xsl:variable name="ids" select="distinct-values((//@BusinessSiteId))"/>
<xsl:template match="/">
    <html>
        <body>
            <h2>Weekly Report</h2>
            <p>Report date/time: <xsl:value-of select="/data/report/@datetime"/></p>
            <p><xsl:value-of select="/data/reportnumber/@displayas"/>: <xsl:value-of
                    select="/data/reportnumber"/></p>
            <p><xsl:value-of select="/data/businessdate/@displayas"/>: <xsl:value-of
                    select="/data/businessdate"/></p>
            <p><xsl:value-of select="/data/businesssiteids/@displayas"/>: <xsl:value-of
                    select="/data/businesssiteids"/></p>
            <xsl:for-each select="$ids">
                <h4>Site ID: <xsl:value-of select="."/></h4>
                <table>
                    <thead>
                        <tr>
                            <th/>
                            <xsl:apply-templates select="$days" mode="header"/>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>Closing Reading:</td>
                            <xsl:apply-templates select="$days" mode="closing">
                                <xsl:with-param name="currentid" select="."/>
                            </xsl:apply-templates>
                        </tr>
                        <tr>
                            <td>Opening Reading:</td>
                            <xsl:apply-templates select="$days" mode="opening">
                                <xsl:with-param name="currentid" select="."/>
                            </xsl:apply-templates>
                        </tr>
                        <tr>
                            <td>Gross Sales:</td>
                            <xsl:apply-templates select="$days" mode="sales">
                                <xsl:with-param name="currentid" select="."/>
                            </xsl:apply-templates>
                        </tr>
                    </tbody>
                </table>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>
<xsl:template match="/data/colheaders/colheader/@*" mode="header">
    <th>
        <xsl:value-of select="."/>
    </th>
</xsl:template>
<xsl:template match="/data/colheaders/colheader/@*" mode="closing">
    <xsl:param name="currentid"/>
    <xsl:variable
        select="concat(substring-after(substring-after(.,'/'),'/') , '-', substring-before(.,'/'), '-', substring-before(substring-after(.,'/'),'/'))"
        name="closedate"/>
    <xsl:for-each select=".">
        <xsl:choose>
            <xsl:when
                test="/data/row/@BusinessDate[../@BusinessSiteId=$currentid][../@ListName='Closing Reading:'][contains(.,$closedate)]">
                <xsl:variable name="numbera" select="/data/row/@BusinessDate[../@BusinessSiteId=$currentid][../@ListName='Closing Reading:'][contains(.,$closedate)]/../@ReportAmtDaily"/>
                <td>
                    <xsl:value-of
                        select="format-number( round(100*$numbera) div 100 ,
                        '###,###,##0.00' )"
                    />
                </td>
            </xsl:when>
            <xsl:otherwise>
                <td>
                    <xsl:text>0</xsl:text>
                </td>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>
<xsl:template match="/data/colheaders/colheader/@*" mode="opening">
    <xsl:param name="currentid"/>
    <xsl:variable
        select="concat(substring-after(substring-after(.,'/'),'/') , '-', substring-before(.,'/'), '-', substring-before(substring-after(.,'/'),'/'))"
        name="opendate"/>
    <xsl:for-each select=".">
        <xsl:choose>
            <xsl:when
                test="/data/row/@BusinessDate[../@BusinessSiteId=$currentid][../@ListName=' - Opening Reading'][contains(.,$opendate)]">
                <xsl:variable name="numberb" select="/data/row/@BusinessDate[../@BusinessSiteId=$currentid][../@ListName=' - Opening Reading'][contains(.,$opendate)]/../@ReportAmtDaily"/>
                <td>
                    <xsl:value-of
                        select="format-number( round(100*$numberb) div 100 ,
                        '###,###,##0.00' )"
                    />
                </td>
            </xsl:when>
            <xsl:otherwise>
                <td>
                    <xsl:text>0</xsl:text>
                </td>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>
<xsl:template match="/data/colheaders/colheader/@*" mode="sales">
    <xsl:param name="currentid"/>
    <xsl:variable
        select="concat(substring-after(substring-after(.,'/'),'/') , '-', substring-before(.,'/'), '-', substring-before(substring-after(.,'/'),'/'))"
        name="salesdate"/>
    <xsl:for-each select=".">
        <xsl:choose>
            <xsl:when
                test="/data/row/@BusinessDate[../@BusinessSiteId=$currentid][../@ListName='Gross Sales:'][contains(.,$salesdate)]">
                <xsl:variable name="numberc" select="/data/row/@BusinessDate[../@BusinessSiteId=$currentid][../@ListName='Gross Sales:'][contains(.,$salesdate)]/../@ReportAmtDaily"/>
                <td>
                    <xsl:value-of
                        select="format-number( round(100*$numberc) div 100 ,
                        '###,###,##0.00' )"
                    />
                </td>
            </xsl:when>
            <xsl:otherwise>
                <td>
                    <xsl:text>0</xsl:text>
                </td>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>