我已经开始使用XSL,并且遇到了唯一动态列数据的问题。我读过类似的问题,但这种情况似乎足够不同,我看不到这些解决方案在这个问题上的应用。
我有以下示例数据集,可以使用大量的<ID>
和<Date>
值进行增长或收缩:
<Report>
<DataSets>
<Data>
<ID>1</ID>
<Date>201211</Date>
</Data>
<Data>
<ID>1</ID>
<Date>201211</Date>
</Data>
<Data>
<ID>1</ID>
<Date>201210</Date>
</Data>
<Data>
<ID>2</ID>
<Date>201209</Date>
</Data>
<Data>
<ID>1</ID>
<Date>201208</Date>
</Data>
<Data>
<ID>2</ID>
<Date>201208</Date>
</Data>
<Data>
<ID>3</ID>
<Date>201208</Date>
</Data>
<Data>
<ID>3</ID>
<Date>201208</Date>
</Data>
</DataSets>
</Report>
我正在尝试获取XSL代码以生成下表:
ID 201208 201209 201210 201211
1 1 0 1 2
2 1 1 0 0
3 2 0 0 0
列是动态的,列标题是<Date>
元素的唯一值。行是唯一ID的集合,数据是每个<Date>
的所述<ID>
的计数。我正在努力的是为每个<Date>
动态创建<ID>
的计数。
到目前为止,我有以下XSL文件,使用键生成表,但正如您所看到的,日期是硬编码的atm。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" >
<xsl:template match ="/" >
<html>
<body>
<xsl:apply-templates select="Report/DataSets"/>
</body>
</html>
</xsl:template>
<xsl:key name="Data_ID" match="Data" use="ID" />
<xsl:key name="Data_D" match="Data" use="Date"/>
<xsl:template match="Report/DataSets" >
<table>
<tr>
<th>ID</th>
<xsl:for-each select="Data[generate-id(.) = generate-id(key('Data_D', Date)[1])]">
<xsl:sort select="Date"/>
<!-- Dynamically add headers for each Date Column -->
<th><xsl:value-of select="Date"/></th>
</xsl:for-each>
</tr>
<xsl:for-each select="Data[generate-id(.) = generate-id(key('Data_ID', ID)[1])]">
<xsl:sort select="ID"/>
<tr>
<td><xsl:value-of select="ID"/></td>
<!-- Dynamically count IDs for each Date Column -->
<!-- How to do this step? -->
<td><xsl:value-of select="count(key('Data_ID', ID)[Date='201208'])"/></td>
<td><xsl:value-of select="count(key('Data_ID', ID)[Date='201209'])"/></td>
<td><xsl:value-of select="count(key('Data_ID', ID)[Date='201210'])"/></td>
<td><xsl:value-of select="count(key('Data_ID', ID)[Date='201211'])"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
需要什么来替换这些硬编码条目
<td><xsl:value-of select="count(key('Data_ID', ID)[Date='201208'])"/></td>
<td><xsl:value-of select="count(key('Data_ID', ID)[Date='201209'])"/></td>
<td><xsl:value-of select="count(key('Data_ID', ID)[Date='201210'])"/></td>
<td><xsl:value-of select="count(key('Data_ID', ID)[Date='201211'])"/></td>
使用动态代码?
您可以使用与头相同类型的for-each
<!-- store the full set of Data in a variable - we will need it inside the for-eaches -->
<xsl:variable name="allData" select="Data"/>
<xsl:for-each select="$allData[generate-id(.) = generate-id(key('Data_ID', ID)[1])]">
<xsl:sort select="ID"/>
<xsl:variable name="currentId" select="ID" />
<tr>
<td><xsl:value-of select="$currentId"/></td>
<!-- Dynamically count IDs for each Date Column -->
<xsl:for-each select="$allData[generate-id(.) = generate-id(key('Data_D', Date)[1])]">
<xsl:sort select="Date"/>
<td>
<xsl:value-of select="count(key('Data_ID', $currentId)[Date=current()/Date])"/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
这里的技巧是将外部for-each
中的ID
保存在一个变量中,这样您就可以在内部for-each
中访问它。
一个可能更有效的替代方案是在ID和日期上定义第三个密钥
<xsl:key name="Data_ID_D" match="Data" use="concat(ID, '|', Date)" />
这将简化CCD_ 12表达
<xsl:for-each select="$allData[generate-id(.) = generate-id(key('Data_D', Date)[1])]">
<xsl:sort select="Date"/>
<td>
<xsl:value-of select="count(key('Data_ID_D', concat($currentId, '|', Date)))"/>
</td>
</xsl:for-each>