项目1 | 项目2 | 项目3 | 项目4 | 项目5 | 合计 | |
---|---|---|---|---|---|---|
级别1 | \ | 10.47 | 30.58 | \ | 42.71 | 83.76 |
级别2 | 35.14 | \ | 59.90 | \ | 68.66 | 163.70 |
级别3 | 18.17 | 69.24 | \ | \ | 78.29 | 165.69 |
级别4 | 33.33 | 32.20 | 91.37 | \ | 27.87 | 184.77 |
级别5 | 34.63 | 91.71 | 18.51 | 39.30 | \ | 184.14 |
合计 | 121.26 | 203.61 | 200.35 | 39.30 | 217.53 | 782.06 |
数据文件用XML存储,如下:
<?xml version="1.0" encoding="utf-16"?>
<StatResult>
<GradeGroup Name="级别1">
<Item Name="项目2">10.47262</Item>
<Item Name="项目3">30.57555</Item>
<Item Name="项目5">42.70821</Item>
</GradeGroup>
<GradeGroup Name="级别2">
<Item Name="项目1">35.13773</Item>
<Item Name="项目3">59.90308</Item>
<Item Name="项目5">68.66362</Item>
</GradeGroup>
<GradeGroup Name="级别3">
<Item Name="项目1">18.16914</Item>
<Item Name="项目2">69.23569</Item>
<Item Name="项目5">78.28595</Item>
</GradeGroup>
<GradeGroup Name="级别5">
<Item Name="项目1">34.62713</Item>
<Item Name="项目2">91.70789</Item>
<Item Name="项目3">18.50808</Item>
<Item Name="项目4">39.30014</Item>
</GradeGroup>
<GradeGroup Name="级别4">
<Item Name="项目1">33.33007</Item>
<Item Name="项目2">32.19778</Item>
<Item Name="项目3">91.3653</Item>
<Item Name="项目5">27.8748</Item>
</GradeGroup>
</StatResult>
用xsl 转换为html,考虑到每一个Item项实际上是由GradeGroup和Item的Name值唯一确定的,所以在输出时,需要用它们的Name共同作为 关键字。由于html是逐行输出的,所以在转换时,可以先按照Item的Name取得具有相同值的节点,然后根据它们的父节点GradeGroup的 Name确定Item输出的行顺序和列位置按照这种想法,xsl的主要代码如下:
<xsl:key name="ItemKey" match="Item" use="@Name"/>
...
<Body>
<Table cellspacing="1px">
<Tr>
<td />
<!--显示每个唯一项目项的名称-->
<xsl:for-each select="//Item[generate-id(.)=generate-id(key('ItemKey',@Name))]">
<xsl:sort select="@Name"/>
<th class="FieldCell">
<xsl:value-of select="@Name"/>
</th>
</xsl:for-each>
<th class="SumCell">合计</th>
</Tr>
<!--逐个处理GradeGroup节点-->
<xsl:for-each select="GradeGroup">
<xsl:sort select="@Name"/>
<!--当前GradeGroup节点的Name值-->
<xsl:variable name="curGradeName">
<xsl:value-of select="@Name"/>
</xsl:variable>
<tr>
<th class="FieldCell">
<xsl:value-of select="@Name"/>
</th>
<!--挑选同名的Item节点-->
<xsl:for-each select="//Item[generate-id(.)=generate-id(key('ItemKey',@Name)[1])]">
<xsl:sort select="@Name"/>
<xsl:variable name="curItemName" select="@Name"/>
<!--从中找到属于当前GradeGroup的Item节点-->
<xsl:variable name="lstItem" select="//Item[@Name=$curItemName and ../@Name=$curGradeName]"/>
<!--显示Item-->
<xsl:call-template name="ShowItem">
<xsl:with-param name="lstItem" select="$lstItem"/>
</xsl:call-template>
</xsl:for-each>
<!--按"级别"计算合计值-->
<td class="NumCell3">
<xsl:value-of select="format-number(sum(//Item[../@Name=$curGradeName]),'#.00')"/>
</td>
</tr>
</xsl:for-each>
<!--按"项目"计算合计值-->
<tr>
<th class="SumCell">合计</th>
<xsl:for-each select="//Item[generate-id(.)=generate-id(key('ItemKey',@Name))]">
<xsl:sort select="@Name"/>
<xsl:variable name="curItemName" select="@Name"/>
<td class="NumCell3">
<xsl:value-of select="format-number(sum(//Item[@Name=$curItemName]),'#.00')"/>
</td>
</xsl:for-each>
<!--总的合计值-->
<td class="NumCell3">
<xsl:value-of select="format-number(sum(//Item),'#.00')"/>
</td>
</tr>
</Table>
</Body>
</Html>
</xsl:template>
<xsl:template name="ShowItem">
<xsl:param name="lstItem"/>
<xsl:if test="count($lstItem)=0">
<td class="NumCell2">\</td>
</xsl:if>
<xsl:if test="count($lstItem)=1">
<td class="NumCell1">
<xsl:value-of select="format-number($lstItem[1],'#.00')"/>
</td>
</xsl:if>
</xsl:template>