我在使用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>
下面的样式表应该完成这项工作。它有两个可配置参数:
- 统计代码匹配
- 等级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>
</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>