给出以下XSLT和XML:
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:template match="/*">
<html>
<head>
<style type="text/css">
.exceed{background:yellow;}
table{border-collapse:collapse;
cellspacing:0px;
cellpadding:5px;
width:90%;}
.total-hours{background-color:#808080;}
.total-row-text{font-weight:bold;}
.report-header{background-color:#C6BD94;}
/*{background-color:#FFFFBB;
}*/
.Report { width: 90%; font-family:Cambria,serif; font-size:14px }
.Report th { border: solid 1px }
.Report td { padding:5px; padding-left:20px; padding-right:20px; border: solid 1px }
tr{background-color:#FFFFBB;}
</style>
</head>
<body>
<div class='ReportDescription'>
</div>
<div class='ReportDate'>
</div>
<table class="Report">
<tr class="report-header">
<xsl:for-each select="headers/header">
<th class="report-Header">
<xsl:value-of select="title"/>
</th>
</xsl:for-each>
</tr>
<xsl:apply-templates mode="Gray" select="PreviousDays/Employee[@total]">
</xsl:apply-templates>
<xsl:apply-templates mode="normal" select="PreviousDays/Employee[not(@total)]">
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="PreviousDays/Employee" mode="Gray">
<tr class="total-hours">
<td class="total-row-text">
<xsl:value-of select="WorkingDate"/>
</td>
<td class="total-row-text">
<xsl:value-of select="@Name"/>
</td>
<td class="total-row-text">
<xsl:value-of select="totalhours"/>
</td>
<td class="total-row-text">
<xsl:value-of select="Description"/>
</td>
</tr>
</xsl:template>
<xsl:template mode="normal" match="PreviousDays/Employee">
<tr class="exceed">
<td>
<xsl:value-of select="WorkingDate"/>
</td>
<td>
<xsl:value-of select="@Name"/>
</td>
<td>
<xsl:value-of select="HoursOnProject"/>
</td>
<td>
<xsl:value-of select="Department"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
XML
<root>
<headers>
<header><title>Header1</title></header>
<header><title>Header2</title></header>
<header><title>Header3</title></header>
<header><title>Header4</title></header>
</headers>
<PreviousDays>
<Employee Name="Martin Davis">
<WorkingDate>9/12/2013</WorkingDate>
<HoursOnProject>8</HoursOnProject>
<Description>Description here</Description>
</Employee>
<Employee total="true" Name="Martin Davis">
<WorkingDate>9/12/2013</WorkingDate>
<HoursOnProject></HoursOnProject>
<Description>Description here</Description>
<totalhours>8</totalhours>
</Employee>
<Employee Name="Caroline Jackson">
<WorkingDate>9/15/2013</WorkingDate>
<HoursOnProject>8.50</HoursOnProject>
<Description>Description here</Description>
</Employee>
<Employee total="true" Name="Caroline Jackson">
<WorkingDate>9/15/2013</WorkingDate>
<HoursOnProject></HoursOnProject>
<Description>Description here</Description>
<totalhours>10</totalhours>
</Employee>
</PreviousDays>
</root>
如何确保通过name属性和WorkingDate对数据进行排序或分组,以便每个单独记录的总行直接显示在任何正常行之后?最好不使用for-each或if type语句。 (不过,欢迎使用这些类型的解决方案。)
期望的输出
<table class="Report">
<tr class="report-header">
<th class="report-Header">Header1</th>
<th class="report-Header">Header2</th>
<th class="report-Header">Header3</th>
<th class="report-Header">Header4</th>
</tr>
<tr class="exceed">
<td>9/12/2013</td>
<td>Martin Davis</td>
<td>8</td>
<td></td>
</tr>
<tr class="total-hours">
<td class="total-row-text">9/12/2013</td>
<td class="total-row-text">Martin Davis</td>
<td class="total-row-text">8</td>
<td class="total-row-text">Description here</td>
</tr>
<tr class="exceed">
<td>9/15/2013</td>
<td>Caroline Jackson</td>
<td>8.50</td>
<td></td>
</tr>
<tr class="total-hours">
<td class="total-row-text">9/15/2013</td>
<td class="total-row-text">Caroline Jackson</td>
<td class="total-row-text">10</td>
<td class="total-row-text">Description here</td>
</tr>
</table>
请注意,如果可以避免,我不想切换到 XSLT 2.0 。
答案 0 :(得分:0)
你可以尝试这个xsl:
<?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">
<!-- Employee without @total grouped by Name -->
<xsl:key name="employees-by-name" match="/root/PreviousDays/Employee[not(@total)]" use="@Name" />
<!-- Employee with @total grouped by Name -->
<xsl:key name="employees-total-by-name" match="/root/PreviousDays/Employee[@total]" use="@Name" />
<!-- templates for writting the trs -->
<xsl:template match="Employee" mode="css-class">
<tr class="exceed">
<xsl:apply-templates select="." mode="contents" />
</tr>
</xsl:template>
<xsl:template match="Employee[@total='true']" mode="css-class">
<tr class="total-hours">
<xsl:apply-templates select="." mode="contents" />
</tr>
</xsl:template>
<!-- template for writting the tds -->
<xsl:template match="Employee" mode="contents">
<td><xsl:value-of select="WorkingDate"/></td>
<td><xsl:value-of select="@Name"/></td>
<td><xsl:value-of select="HoursOnProject"/></td>
<td><xsl:value-of select="Department"/></td>
</xsl:template>
<xsl:template match="/root">
<html>
<head>
<style type="text/css">
.exceed{background:yellow;}
table{border-collapse:collapse;cellspacing:0px;cellpadding:5px;width:90%;}
.total-hours td{background-color:#808080;font-weight:bold;}
.report-header{background-color:#C6BD94;}
.Report {width: 90%; font-family:Cambria,serif; font-size:14px;}
.Report th {border: solid 1px;}
.Report td {padding:5px; padding-left:20px; padding-right:20px; border: solid 1px;}
tr{background-color:#FFFFBB;}
</style>
</head>
<body>
<div class='ReportDescription'>
</div>
<div class='ReportDate'>
</div>
<table class="Report">
<tr class="report-header">
<xsl:for-each select="headers/header">
<th class="report-Header">
<xsl:value-of select="title"/>
</th>
</xsl:for-each>
</tr>
<!-- loop for each Employee which does not have a preceding-sibling with same @Name -->
<xsl:for-each select="PreviousDays/Employee[not(@Name = preceding-sibling::Employee/@Name)]">
<!-- apply templates for those elements with same @Name and not @total attribute -->
<xsl:apply-templates select="key('employees-by-name',@Name)" mode="css-class">
<xsl:sort select="WorkingDate" />
</xsl:apply-templates>
<!-- apply templates for those -or that- elements with same @Name and with @total attribute -->
<xsl:apply-templates select="key('employees-total-by-name',@Name)" mode="css-class" />
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>