我一直试图弄清楚为什么我的变量赋值和不起作用,我的表输出也只重复整个表中的第一个元素。我想要获得此代码的目的是获取第一列中打印的每个学生的studentID,第二列中该ID的学生姓名,然后分配一个变量,其中包含3个评估的学生总分已完成在第三列中打印其总标记,然后根据其总标记分配HD,D,C,P或F,例如HD为85加,D为75 +但不高于84等。
有人能告诉我哪里出错了吗?我还是XML / XSL的新手,所以欢迎批评。
grade.xsl
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="StudentAmount" select="count(document('AssessmentItems.xml')/assessmentList/unit/studentList/student)"/>
<xsl:variable name="totalmark" select="sum(document('AssessmentItems.xml')/assessmentList/unit/*
[//assessmentList/unit/assessmentItems/assessment/@studId = //assessmentList/unit/studentList/student/@sid])"/>
<html>
<body>
<h2>Grade Report for <xsl:value-of select="assessmentList/unit/@unitId"/> - <xsl:value-of select="assessmentList/unit/unitName"/></h2>
<p>Number of students in this unit: <xsl:value-of select="$StudentAmount"/></p>
<table border="1">
<tr>
<th>ID</th>
<th>Name</th>
<th>Total Mark</th>
<th>Grade</th>
</tr>
<xsl:for-each select="assessmentList/unit/studentList/student">
<tr>
<td><xsl:value-of select="document('AssessmentItems.xml')/assessmentList/unit/studentList/student/@sid"/></td>
<td><xsl:value-of select="document('AssessmentItems.xml')/assessmentList/unit/studentList/student"/></td>
<td><xsl:value-of select="document('AssessmentItems.xml')/assessmentList/unit/assessmentItems/assessment/mark"/></td>
<xsl:choose>
<xsl:when test="$totalmark > 85">
<td color="blue">HD</td>
</xsl:when>
<xsl:when test="$totalmark > 75">
<td color="black">D</td>
</xsl:when>
<xsl:when test="$totalmark > 65">
<td color="black">C</td>
</xsl:when>
<xsl:when test="$totalmark > 50">
<td color="black">P</td>
</xsl:when>
<xsl:otherwise>
<td color="red">F</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
这是文件AssessmentItems.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="grade.xsl"?>
<assessmentList>
<unit unitId="3311">
<unitName>Learn To Read</unitName>
<studentList>
<student sid="1001">Lisa Simpson</student>
<student sid="1002">Barney Rubble</student>
<student sid="1003">Donald Duck</student>
</studentList>
<assessmentItems>
<assessment name="Assignment 1" weight="20">
<mark studId="1001">12</mark>
<mark studId="1002">18</mark>
<mark studId="1003">9</mark>
</assessment>
<assessment name="Assignment 2" weight="25">
<mark studId="1001">23</mark>
<mark studId="1002">14</mark>
<mark studId="1003">12.5</mark>
</assessment>
<assessment name="Quiz" weight="15">
<mark studId="1001">13</mark>
<mark studId="1002">9</mark>
<mark studId="1003">6</mark>
</assessment>
<assessment name="Final Exam" weight="40">
<mark studId="1001">38</mark>
<mark studId="1002">21</mark>
<mark studId="1003">20.5</mark>
</assessment>
</assessmentItems>
</unit>
</assessmentList>
答案 0 :(得分:0)
首先,因为您只处理单个XML文档,所以根本不需要对文档('AssessmentItems.xml')的常量引用。所以,例如
<xsl:value-of
select="document('AssessmentItems.xml')/assessmentList/unit/studentList/student/@sid"/>
可以用
替换<xsl:value-of select="/assessmentList/unit/studentList/student/@sid"/>
这引出了第二个问题。上面的xpath是相对于XML的document元素的,它将返回它找到的第一个学生的@sid,而不是你当前所在学生的@sid。您只需在您的情况下执行此操作
<xsl:value-of select="@sid"/>
另一个问题是您在XSLT顶部定义变量 totalmarks ,实际上它应该在 xsl:for-each 的范围内定义因此它特定于当前学生
<xsl:variable name="totalmark" select="sum(../../assessmentItems/assessment/mark[@studId = current()/@sid])" />
实际上,最好在这里使用密钥来查找结果
<xsl:key name="marks" match="mark" use="@studId" />
获得学生的总成绩......
<xsl:variable name="totalmark" select="sum(key('marks', @sid))" />
最后一条评论虽然不是问题,但通常最好使用 xsl:apply-templates 而不是 xsl:for-each ,因为这可以避免过度缩进,并允许更好的代码重用。
尝试以下XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="marks" match="mark" use="@studId"/>
<xsl:template match="/">
<xsl:variable name="StudentAmount" select="count(/assessmentList/unit/studentList/student)"/>
<html>
<body>
<h2>Grade Report for
<xsl:value-of select="assessmentList/unit/@unitId"/>-
<xsl:value-of select="assessmentList/unit/unitName"/>
</h2>
<p>Number of students in this unit:
<xsl:value-of select="$StudentAmount"/></p>
<table border="1">
<tr>
<th>ID</th>
<th>Name</th>
<th>Total Mark</th>
<th>Grade</th>
</tr>
<xsl:apply-templates select="assessmentList/unit/studentList/student"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="student">
<xsl:variable name="totalmark" select="sum(key('marks', @sid))"/>
<tr>
<td>
<xsl:value-of select="@sid"/>
</td>
<td>
<xsl:value-of select="."/>
</td>
<td>
<xsl:value-of select="$totalmark"/>
</td>
<xsl:choose>
<xsl:when test="$totalmark > 85">
<td color="blue">HD</td>
</xsl:when>
<xsl:when test="$totalmark > 75">
<td color="black">D</td>
</xsl:when>
<xsl:when test="$totalmark > 65">
<td color="black">C</td>
</xsl:when>
<xsl:when test="$totalmark > 50">
<td color="black">P</td>
</xsl:when>
<xsl:otherwise>
<td color="red">F</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:template>
</xsl:stylesheet>
应用于XML时,输出以下HTML
<html>
<body>
<h2>Grade Report for 3311- Learn To Read</h2>
<p>Number of students in this unit: 3</p>
<table border="1">
<tr>
<th>ID</th>
<th>Name</th>
<th>Total Mark</th>
<th>Grade</th>
</tr>
<tr>
<td>1001</td>
<td>Lisa Simpson</td>
<td>86</td>
<td color="blue">HD</td>
</tr>
<tr>
<td>1002</td>
<td>Barney Rubble</td>
<td>62</td>
<td color="black">P</td>
</tr>
<tr>
<td>1003</td>
<td>Donald Duck</td>
<td>48</td>
<td color="red">F</td>
</tr>
</table>
</body>
</html>
请注意,这假设您的XML中只有一个 unit 元素。如果您的实际XML有多个单元,并且您希望每个单元都有一个单独的表,那么这不是问题,您只需要确保单元ID是 xsl:key 的一部分,这样您就可以了可以查找给定单位中给定学生的结果。
答案 1 :(得分:0)
快速浏览一下代码就会发现谓词
[//assessmentList/unit/assessmentItems/assessment/@studId = //assessmentList/unit/studentList/student/@sid]
显然是错误的,因为它对源文档中的每个元素都具有相同的值(true或false)。
纠正它需要比我有时间更多地研究问题。但你似乎成了“如果它不起作用然后把'//'放在前面”谬误的受害者。