【问题标题】:XSLT GROUP BY using keysXSLT GROUP BY 使用键
【发布时间】:2013-03-03 06:15:50
【问题描述】:

我正在尝试生成 HTML 输出,它是以下层次结构中的表 - DIVISION、DESK、STRATEGY。我需要在 Division 列和 Desk 列上设置行跨度。一个部门可以有多张办公桌,一张办公桌可以有多种策略。

我正在使用键来按 Division,Desk 定义分组。它适用于 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>

【问题讨论】:

    标签: xslt xslt-grouping


    【解决方案1】:

    这有点棘手,但应该这样做:

    <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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-26
      • 1970-01-01
      • 2011-01-09
      • 2012-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多