XSLT1如何按2个元素进行分组



我在使用2个元素对一些xml进行分组时遇到了一些问题。虽然使用2.0版本可以很容易地做到这一点,但我被限制为xslt 1.0:(.

我想实现的是只得到统计代码为1的学生,然后按等级对他们进行分组。最后,我得到了每个课程名称的出勤率总和:

|---------------------|------------------|
|      CourseName     |     Attendance   |
|---------------------|------------------|
|          Bio        |         17       |
|---------------------|------------------|
|          Math       |         31       |
|---------------------|------------------|

这是我正在使用的xml:

<Student>
<statisticsCode>-1</statisticsCode>
<attendance>15</attendance>
<groupid>1</groupid>
<statisticsCode>3</statisticsCode>
<Grade>
<gradeId>1</gradeId>
<uidObjectID>00010004-0000-0000-0000-000000000031</uidObjectID>
<CourseName>Science</CourseName>
</Grade>
</Student>
<Student>
<statisticsCode>-1</statisticsCode>
<attendance>31</attendance>
<groupid>1</groupid>
<statisticsCode>1</statisticsCode>
<Grade>
<gradeId>1</gradeId>
<uidObjectID>00010004-0000-0000-0000-000000000031</uidObjectID>
<CourseName>Math</CourseName>
</Grade>
</Student>
<Student>
<statisticsCode>-1</statisticsCode>
<attendance>14</attendance>
<groupid>1</groupid>
<statisticsCode>1</statisticsCode>
<Grade>
<gradeId>2</gradeId>
<uidObjectID>00010004-0000-0000-0000-000000000031</uidObjectID>
<CourseName>Bio</CourseName>
</Grade>
</Student>
<Student>
<statisticsCode>-1</statisticsCode>
<attendance>3</attendance>
<groupid>1</groupid>
<statisticsCode>1</statisticsCode>
<Grade>
<gradeId>2</gradeId>
<uidObjectID>00010004-0000-0000-0000-000000000031</uidObjectID>
<CourseName>Bio</CourseName>
</Grade>
</Student>  

下面的样式表应该完成这项工作。它有两个可配置参数:

  1. 统计代码匹配
  2. 等级ID匹配

论文的值当前设置为1,因此将根据您的要求筛选学生,并且在当前设置中,将仅汇总第一年级学生的出勤率。

希望有帮助;-(

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xd" version="1.0">
<xd:doc scope="stylesheet">
<xd:desc>
<xd:p><xd:b>Created on:</xd:b> Apr 9, 2020</xd:p>
<xd:p><xd:b>Author:</xd:b> bwb</xd:p>
<xd:p/>
</xd:desc>
</xd:doc>
<xsl:output method="text"/>
<xsl:param name="statisticsCode-match">1</xsl:param>
<xsl:variable name="line-divider">
<xsl:text>|--------------------|--------------------|</xsl:text>
</xsl:variable>
<xsl:variable name="break">
<xsl:text>&#xa;</xsl:text>
</xsl:variable>
<xsl:variable name="students.filtered">
<xsl:for-each select="//Student[statisticsCode = $statisticsCode-match]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="coursenames.distinct">
<xsl:for-each select="//Student[statisticsCode = $statisticsCode-match]//CourseName">
<xsl:choose>
<xsl:when test=". = preceding::CourseName"/>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="twenty-whitespaces">
<xsl:text>                    </xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:value-of select="$break"/>
<xsl:text>statisticsCode: </xsl:text>
<xsl:value-of select="$statisticsCode-match"/>
<xsl:value-of select="$break"/>
<xsl:value-of select="$line-divider"/>
<xsl:value-of select="$break"/>
<xsl:text>|     CourseName     |     Attendance     |</xsl:text>
<xsl:value-of select="$break"/>
<xsl:value-of select="$line-divider"/>
<xsl:for-each select="//Student[statisticsCode = $statisticsCode-match]//CourseName">
<xsl:choose>
<xsl:when test=". = preceding::CourseName"/>
<xsl:otherwise>
<!-- course name -->
<xsl:variable name="padding.course" select="substring($twenty-whitespaces, 1, floor((20 - string-length(.)) div 2))"/>
<xsl:value-of select="$break"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="$padding.course"/>
<xsl:value-of select="."/>
<xsl:value-of select="$padding.course"/>
<xsl:if test="string-length(.) mod 2 = 1">
<xsl:text> </xsl:text>
</xsl:if>
<!-- end course name -->
<xsl:text>|</xsl:text>
<!-- attendance -->
<xsl:variable name="attendance.count" select="sum(//Student[statisticsCode = $statisticsCode-match][Grade[CourseName = current()]]/attendance)"/>
<xsl:variable name="padding.attendance" select="substring($twenty-whitespaces, 1, floor((20 - string-length($attendance.count)) div 2))"/>
<xsl:value-of select="$padding.attendance"/>
<xsl:value-of select="$attendance.count"/>
<xsl:value-of select="$padding.attendance"/>
<xsl:if test="string-length($attendance.count) mod 2 = 1">
<xsl:text> </xsl:text>
</xsl:if>
<!-- end attendance -->
<xsl:text>|</xsl:text>
<!-- table divider -->
<xsl:value-of select="$break"/>
<xsl:value-of select="$line-divider"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

相关内容

  • 没有找到相关文章

最新更新