2013-03-03 52 views
0

我想要生成HTML輸出,它是以下層次結構中的表格 - 分區,桌面,策略。我需要在Division列和Desk列上設置rowspan。一個部門可以有多個辦公桌,一個辦公桌可以有多個策略。XSLT GROUP BY使用密鑰

我正在使用鍵來按照Division,Desk定義分組。它適用於部門,但打破了桌面。請指教。

XML代碼:

<?xml version="1.0"?> 
<ROWSET> 
<ROW> 
    <DIVISION>Flow Credit</DIVISION> 
    <DESK>Europe Indices Net</DESK> 
    <ACCT_PNL>  0.18 MM USD</ACCT_PNL> 
    <ECO_PNL>  0.00 MM USD</ECO_PNL> 
</ROW> 
<ROW> 
    <DIVISION>Flow Credit</DIVISION> 
    <DESK>US CDS Trading</DESK> 
    <STRATEGY>Funk_A6M</STRATEGY> 
    <ACCT_PNL> -0.01 MM USD</ACCT_PNL> 
    <ECO_PNL>  0.00 MM USD</ECO_PNL> 
</ROW> 
<ROW> 
    <DIVISION>Flow Credit</DIVISION> 
    <DESK>US CDS Trading</DESK> 
    <STRATEGY>HYQUANTO</STRATEGY> 
    <ACCT_PNL>  0.01 MM USD</ACCT_PNL> 
    <ECO_PNL>  0.00 MM USD</ECO_PNL> 
</ROW> 

XSLT:

<?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="groups" match="/ROWSET/ROW" use="DIVISION"/> 
<xsl:key name="groups2" match="/ROWSET/ROW" use="concat(DIVISION, '|', DESK)"/> 
<xsl:template match="/ROWSET/ROW"> 
    <xsl:apply-templates select="result[generate-id() = generate-id(key('groups', DIVISION)[1])]" mode="groups"/> 
    <xsl:apply-templates select="result[generate-id() = generate-id(key('groups2', concat(DIVISION, '|', DESK))[1])]" mode="groups2"/> 
</xsl:template> 
<xsl:template match="/ROWSET"> 
    <h1> 
     <xsl:value-of select="DIVISION"/> 
    </h1> 
    <table id="{DIVISION}"> 
     <tr class="heading"> 
      <th scope="col">DIVISION</th> 
      <th scope="col">DESK</th> 
      <th scope="col">STRATEGY</th> 
     </tr> 
     <xsl:for-each select="key('groups', ROW/DIVISION)"> 
      <tr> 
       <xsl:if test="position() = 1"> 
        <td valign="center" bgcolor="#999999"> 
         <xsl:attribute name="rowspan"> <xsl:value-of select="count(key('groups', DIVISION))"/></xsl:attribute> 
         <b> 
          <xsl:text/> 
          <xsl:value-of select="DIVISION"/> 
         </b> 
        </td> 
       </xsl:if> 
       <xsl:if test="position() = 1"> 
        <td valign="center" bgcolor="#999999"> 
         <xsl:attribute name="rowspan">  <xsl:value-of select="count(key('groups2', concat(DIVISION, '|',DESK)))"/></xsl:attribute> 
         <b> 
          <xsl:text/> 
          <xsl:value-of select="DESK"/> 
         </b> 
        </td> 
       </xsl:if> 
       <td> 
        <xsl:value-of select="STRATEGY"/> 
       </td> 
      </tr> 
     </xsl:for-each> 
    </table> 
</xsl:template> 
</xsl:stylesheet> 

回答

0

這是一個有點棘手,但是這應該這樣做:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:key name="groups" match="/ROWSET/ROW" use="DIVISION"/> 
    <xsl:key name="groups2" match="/ROWSET/ROW" use="concat(DIVISION, '|', DESK)"/> 

    <xsl:template match="/ROWSET"> 
    <xsl:apply-templates select="ROW[generate-id() = 
            generate-id(key('groups', DIVISION)[1])]" /> 
    </xsl:template> 

    <xsl:template match="ROW"> 
    <h1> 
     <xsl:value-of select="DIVISION"/> 
    </h1> 
    <table id="{DIVISION}"> 
     <tr class="heading"> 
     <th scope="col">DIVISION</th> 
     <th scope="col">DESK</th> 
     <th scope="col">STRATEGY</th> 
     </tr> 
     <tr> 
     <xsl:call-template name="DivisionCell" /> 
     <xsl:call-template name="DeskCell" /> 
     <xsl:call-template name="Strategy" /> 
     </tr> 
     <!-- Remaining rows for the first desk --> 
     <xsl:call-template name="DeskRemainder" /> 
     <!-- Apply templates on the first row of each remaining desk --> 
     <xsl:apply-templates 
      select="key('groups', DIVISION) 
        [generate-id() = 
        generate-id(key('groups2', concat(DIVISION, '|', DESK) 
           )[1])] 
        [position() > 1]" mode="deskStarter" /> 
    </table> 
    </xsl:template> 

    <xsl:template name="DivisionCell"> 
    <xsl:call-template name="GroupCell"> 
     <xsl:with-param name="value" select="DIVISION" /> 
     <xsl:with-param name="key" select="'groups'" /> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="DeskCell"> 
    <xsl:call-template name="GroupCell"> 
     <xsl:with-param name="value" select="DESK" /> 
     <xsl:with-param name="key" select="'groups2'" /> 
     <xsl:with-param name="keyValue" select="concat(DIVISION, '|', DESK)" /> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="GroupCell"> 
    <xsl:param name="value" /> 
    <xsl:param name="key" /> 
    <xsl:param name="keyValue" select="$value" /> 

    <td valign="center" bgcolor="#999999" 
     rowspan="{count(key($key, $keyValue))}"> 
     <b> 
     <xsl:value-of select="$value"/> 
     </b> 
    </td> 
    </xsl:template> 

    <xsl:template name="DeskRemainder"> 
    <xsl:apply-templates 
      select="key('groups2', concat(DIVISION, '|', DESK))[position() > 1]" 
      mode="deskRemainder" /> 
    </xsl:template> 

    <!-- For the first row of each distinct desk, after the first distinct desk --> 
    <xsl:template match="ROW" mode="deskStarter"> 
    <tr> 
     <xsl:call-template name="DeskCell" /> 
     <xsl:call-template name="Strategy" /> 
    </tr> 
    <xsl:call-template name="DeskRemainder" /> 
    </xsl:template> 

    <!-- For remaining rows for a given desk --> 
    <xsl:template match="ROW" mode="deskRemainder"> 
    <tr> 
     <xsl:call-template name="Strategy" /> 
    </tr> 
    </xsl:template> 

    <xsl:template name="Strategy"> 
    <td> 
     <xsl:value-of select="STRATEGY"/> 
    </td> 
    </xsl:template> 
</xsl:stylesheet> 

當這個運行輸入XML(帶有額外的項目使其更有趣一些):

<ROWSET> 
    <ROW> 
    <DIVISION>Flow Credit</DIVISION> 
    <DESK>Europe Indices Net</DESK> 
    <ACCT_PNL>  0.18 MM USD</ACCT_PNL> 
    <ECO_PNL>  0.00 MM USD</ECO_PNL> 
    </ROW> 
    <ROW> 
    <DIVISION>Flow Credit</DIVISION> 
    <DESK>US CDS Trading</DESK> 
    <STRATEGY>Funk_A6M</STRATEGY> 
    <ACCT_PNL> -0.01 MM USD</ACCT_PNL> 
    <ECO_PNL>  0.00 MM USD</ECO_PNL> 
    </ROW> 
    <ROW> 
    <DIVISION>Other Division</DIVISION> 
    <DESK>US CDS Trading</DESK> 
    <STRATEGY>HYQUANTO</STRATEGY> 
    <ACCT_PNL>  0.01 MM USD</ACCT_PNL> 
    <ECO_PNL>  0.00 MM USD</ECO_PNL> 
    </ROW> 
    <ROW> 
    <DIVISION>Flow Credit</DIVISION> 
    <DESK>US CDS Trading</DESK> 
    <STRATEGY>HYQUANTO</STRATEGY> 
    <ACCT_PNL>  0.01 MM USD</ACCT_PNL> 
    <ECO_PNL>  0.00 MM USD</ECO_PNL> 
    </ROW> 
    <ROW> 
    <DIVISION>Other Division</DIVISION> 
    <DESK>US CDS Trading</DESK> 
    <STRATEGY>HYQUANTO</STRATEGY> 
    <ACCT_PNL>  0.01 MM USD</ACCT_PNL> 
    <ECO_PNL>  0.00 MM USD</ECO_PNL> 
    </ROW> 
    <ROW> 
    <DIVISION>Other Division</DIVISION> 
    <DESK>Europe CDS Trading</DESK> 
    <STRATEGY>HYQUANTO</STRATEGY> 
    <ACCT_PNL>  0.01 MM USD</ACCT_PNL> 
    <ECO_PNL>  0.00 MM USD</ECO_PNL> 
    </ROW> 
</ROWSET> 

這將產生:

<h1>Flow Credit</h1> 
<table id="Flow Credit"> 
    <tr class="heading"> 
    <th scope="col">DIVISION</th> 
    <th scope="col">DESK</th> 
    <th scope="col">STRATEGY</th> 
    </tr> 
    <tr> 
    <td valign="center" bgcolor="#999999" rowspan="3"> 
     <b>Flow Credit</b> 
    </td> 
    <td valign="center" bgcolor="#999999" rowspan="1"> 
     <b>Europe Indices Net</b> 
    </td> 
    <td></td> 
    </tr> 
    <tr> 
    <td valign="center" bgcolor="#999999" rowspan="2"> 
     <b>US CDS Trading</b> 
    </td> 
    <td>Funk_A6M</td> 
    </tr> 
    <tr> 
    <td>HYQUANTO</td> 
    </tr> 
</table> 
<h1>Other Division</h1> 
<table id="Other Division"> 
    <tr class="heading"> 
    <th scope="col">DIVISION</th> 
    <th scope="col">DESK</th> 
    <th scope="col">STRATEGY</th> 
    </tr> 
    <tr> 
    <td valign="center" bgcolor="#999999" rowspan="3"> 
     <b>Other Division</b> 
    </td> 
    <td valign="center" bgcolor="#999999" rowspan="2"> 
     <b>US CDS Trading</b> 
    </td> 
    <td>HYQUANTO</td> 
    </tr> 
    <tr> 
    <td>HYQUANTO</td> 
    </tr> 
    <tr> 
    <td valign="center" bgcolor="#999999" rowspan="1"> 
     <b>Europe CDS Trading</b> 
    </td> 
    <td>HYQUANTO</td> 
    </tr> 
</table>