我正在尝试生成HTML输出,该输出是以下层次结构上的表--DIVISION,DESK,STRATEGY。我需要在Division列和Desk列上设置rowspan。一个部门可以有多个办公桌,一个办公桌可以有多种策略。
我使用键来分区,桌面定义分组。它适用于分部,但适用于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 :(得分: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>