如何在XSLT的for-each中按当前高中统计男女学生数量?
解决按高中分组统计男女学生数量的问题
看起来你已经搭好了按高中分页的基础框架,但统计男女数量时误用了全局路径,所以得到的是所有高中的总数,而非当前高中的对应数值。下面是调整后的完整解决方案:
1. 先修正XML的语法错误
你的XML里<student>标签的闭合写成了</eleve>,这会导致解析失败,先改成匹配的</student>:
<?xml version='1.0' encoding='UTF-8'?> <students> <student> <number>1</number> <firstname>Sandrine</firstname> <name>BERTIN</name> <gender>F</gender> <highschool>de la Côte d'Albâtre</highschool> <city>Saint-Valéry-en-Caux</city> <specialization>Physique chimie</specialization> </student> <!-- 其他学生数据 --> </students>
2. 调整XSL分组与统计逻辑
首先在XSL样式表顶部定义精准的分组key(考虑到不同城市可能有同名高中,用高中+城市的组合作为key避免分组错误):
<xsl:key name="highschoolCityKey" match="student" use="concat(highschool, '|', city)" />
然后修改分页循环逻辑,在每所高中的块内先获取当前高中的所有学生集合,再基于这个集合统计男女数量:
<fo:page-sequence master-reference="book"> <fo:flow flow-name="xsl-region-body"> <!-- 按城市+高中分组,确保每组对应一所城市里的特定高中 --> <xsl:for-each select="students/student[count(. | key('highschoolCityKey', concat(highschool, '|', city))[1]) = 1]"> <xsl:sort select="city" /> <xsl:sort select="highschool" /> <!-- 定义变量存储当前高中的所有学生集合 --> <xsl:variable name="currentHSStudents" select="key('highschoolCityKey', concat(highschool, '|', city))" /> <!-- 高中标题(分页显示) --> <fo:block break-before="page" font-size="16pt" font-weight="bold"> <xsl:value-of select="highschool"/> </fo:block> <fo:block> City : <xsl:value-of select="city" /> </fo:block> <!-- 统计当前高中的男女学生数 --> <fo:block> Number of male students : <xsl:value-of select="count($currentHSStudents[gender='M'])" /> </fo:block> <fo:block> Number of female students : <xsl:value-of select="count($currentHSStudents[gender='F'])" /> </fo:block> <!-- 学生列表表格 --> <fo:block margin-top="10pt"> <fo:table border="1pt solid black"> <fo:table-column column-width="50pt"/> <fo:table-column column-width="100pt"/> <fo:table-column column-width="100pt"/> <fo:table-column column-width="80pt"/> <fo:table-column column-width="150pt"/> <fo:table-header> <fo:table-row> <fo:table-cell padding="5pt" background-color="#eee"> <fo:block>Number</fo:block> </fo:table-cell> <fo:table-cell padding="5pt" background-color="#eee"> <fo:block>First Name</fo:block> </fo:table-cell> <fo:table-cell padding="5pt" background-color="#eee"> <fo:block>Last Name</fo:block> </fo:table-cell> <fo:table-cell padding="5pt" background-color="#eee"> <fo:block>Gender</fo:block> </fo:table-cell> <fo:table-cell padding="5pt" background-color="#eee"> <fo:block>Specialization</fo:block> </fo:table-cell> </fo:table-row> </fo:table-header> <fo:table-body> <xsl:for-each select="$currentHSStudents"> <xsl:sort select="number"/> <fo:table-row> <fo:table-cell padding="5pt"> <fo:block><xsl:value-of select="number"/></fo:block> </fo:table-cell> <fo:table-cell padding="5pt"> <fo:block><xsl:value-of select="firstname"/></fo:block> </fo:table-cell> <fo:table-cell padding="5pt"> <fo:block><xsl:value-of select="name"/></fo:block> </fo:table-cell> <fo:table-cell padding="5pt"> <fo:block><xsl:value-of select="gender"/></fo:block> </fo:table-cell> <fo:table-cell padding="5pt"> <fo:block><xsl:value-of select="specialization"/></fo:block> </fo:table-cell> </fo:table-row> </xsl:for-each> </fo:table-body> </fo:table> </fo:block> </xsl:for-each> </fo:flow> </fo:page-sequence>
关键逻辑说明
- 用
concat(highschool, '|', city)作为key值,确保只有同一城市的同一高中才会被分到同一组,避免不同城市的同名高中混淆。 - 通过变量
$currentHSStudents获取当前高中的专属学生集合,后续统计和列表都基于这个集合,而非全局的/students/student,这样就能得到当前高中的男女学生数了。 - 学生列表添加了表格样式,你可以根据需求调整列宽、边框、背景色等样式细节。
内容的提问来源于stack exchange,提问作者Tyab
相关产品推荐
相关产品推荐

