Reputation: 357
I am trying to use a true or fale statement within the count function of XPath and am encountering a few errors. Here is my code so far:
<xsl:for-each select="all/courses/allcourses/course">
<xsl:for-each select="student">
<xsl:variable name="StudentTotalPoints" select="sum(results/u_points)" />
<xsl:value-of select="$StudentTotalPoints" />
<xsl:variable name="amountEnrolled" select="count((360 - $StudentTotalPoints) != 0)" />
<xsl:value-of select="$amountEnrolled" />
</xsl:for-each>
</xsl:for-each>
the XML code in question is:
<all>
<courses>
<allcourses>
<course>
<c_code>U65</c_code>
<c_title>Computer Science</c_title>
<coursecp>360</coursecp>
<student>
<studentID>10265654</studentID>
<fname>Sarah</fname>
<lname>Clarke</lname>
<results>
<u_title>Communicating in an IT Environment</u_title>
<u_code>CSG1132</u_code>
<u_points>15</u_points>
<result>65</result>
<grade>CR</grade>
</results>
<results>
<u_title>Programming Principles</u_title>
<u_code>CSP1150</u_code>
<u_points>15</u_points>
<result>45</result>
<grade>N</grade>
</results>
</student>
<student> *same structure* </student>
the problem is on the line where the variable amountEnrolled is declared, when trying to load the page in question I am welcomed with this error:
"Error during XSLT transformation: An XPath expression was expected to return a NodeSet."
So clearly the count function isn't returning anything. What is the best way to go about this? I feel like it should be simple but it definitely isn't. My required result is to count the amount of times that 360 - $StudentTotalPoints does NOT equal to 0
, how should I go about this?
Thanks in advance!
Upvotes: 1
Views: 147
Reputation: 116992
a student will have multiple
<results> </results>
within<student></student>
Okay, then if we take the following example input:
<all>
<courses>
<allcourses>
<course>
<c_code>U65</c_code>
<student>
<studentID>1</studentID>
<results>
<u_points>10</u_points>
</results>
<results>
<u_points>20</u_points>
</results>
<results>
<u_points>30</u_points>
</results>
</student>
<student>
<studentID>2</studentID>
<results>
<u_points>40</u_points>
</results>
<results>
<u_points>50</u_points>
</results>
<results>
<u_points>360</u_points>
</results>
</student>
</course>
</allcourses>
</courses>
</all>
and apply this stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:for-each select="all/courses/allcourses/course">
<course code="{c_code}">
<xsl:for-each select="student">
<student id="{studentID}">
<totalPoints><xsl:value-of select="sum(results/u_points)" /></totalPoints>
<amountEnrolled><xsl:value-of select="count(results/u_points[.!=360])" /></amountEnrolled>
</student>
</xsl:for-each>
</course>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
we will receive:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<course code="U65">
<student id="1">
<totalPoints>60</totalPoints>
<amountEnrolled>3</amountEnrolled>
</student>
<student id="2">
<totalPoints>450</totalPoints>
<amountEnrolled>2</amountEnrolled>
</student>
</course>
</root>
This is probably not what you want, but it does what you say it should do.
Sorry, I forgot to specify, how many times within
<course>
Okay, then we need to move the count to the parent Course element:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:for-each select="all/courses/allcourses/course">
<course code="{c_code}">
<xsl:for-each select="student">
<student id="{studentID}">
<totalPoints><xsl:value-of select="sum(results/u_points)" /></totalPoints>
</student>
</xsl:for-each>
<amountEnrolled>
<xsl:value-of select="count(student[sum(results/u_points)!=360])"/>
</amountEnrolled>
</course>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
If we now modify our input to:
<all>
<courses>
<allcourses>
<course>
<c_code>U65</c_code>
<student>
<studentID>1</studentID>
<results>
<u_points>10</u_points>
</results>
<results>
<u_points>20</u_points>
</results>
<results>
<u_points>30</u_points>
</results>
</student>
<student>
<studentID>2</studentID>
<results>
<u_points>40</u_points>
</results>
<results>
<u_points>50</u_points>
</results>
<results>
<u_points>270</u_points>
</results>
</student>
</course>
</allcourses>
</courses>
</all>
we will receive:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<course code="U65">
<student id="1">
<totalPoints>60</totalPoints>
</student>
<student id="2">
<totalPoints>360</totalPoints>
</student>
<amountEnrolled>1</amountEnrolled>
</course>
</root>
Upvotes: 2