Soon after the launch of the web timetables we were asked by the timetabling project team to investigate the possibility of a self-service feature for staff to produce class lists on demand, as central production and distribution of these was a potential bottleneck.
Scientia colleagues directed us towards an SWS report that produced class lists for activities:
Unfortunately the report presented its data as a series of tables with students sorted by surname in each. This gave us two problems to solve:
- How to give staff a usable interface for generating class lists for activities
- How to order data returned from the report so that it provided a useful class list
Giving staff an interface for selecting class lists
We had already developed a page that would proxy the SWS programmeOfStudy report to produce either a list or grid view of the timetable for any course. This page included a reference to every activity that had been scheduled, which could be passed to the SWS activity report. However, the timetabling team explained that not all of these would have class lists and we knew staff would be disappointed if some links appeared broken. After discussing the problem with Scientia, their consultants produced a custom programmeOfStudy report template that listed all activities for a course with the number of students allocated to each activity. We knew that every activity with a student allocation greater than zero would have a class list, so we had the data necessary to limit link creation to only those that would return a class list. However, the data needed to be scraped from HTML tables.
We decided that our proxy page would need to make two HTTP GET requests: the first would get the course timetable and inject CSS and some form objects (for varying display range and format); the second would get the activity list for the class and process the HTML to produce an array of activities with class lists. Before displaying the (re-formatted) output from the first course timetable request we could then iterate over the array of activities with class lists replacing the activity name in the HTML with a link to the class list page for that activity. When displayed on the screen staff would then have a class list with clickable links for every activity for which a class list was available.
We encountered problems loading the activity list report as XHTML, so we had to load as a string, extract the text between the body tags and remove some invalid characters and elements before we could process it as XML. However, once loaded, we were able to pick out all the activities that had class lists using XPath as the activity references were in the first column of rows without a @class attribute in tables of @class ‘spreadsheet’ which had a non-zero value in the 8th column!
//table[@class=’spreadsheet’]/tr[not(string(@class)) and not(td=’0′)]/td
The page to which we directed staff then had to solve the second problem of displaying useful class lists.
Providing useful class lists
After considerable experimentation, we found we needed to load the class list report as a string and extract certain parts as XML so that we could apply an XSL Transform to sort the students by surname and produce a report that staff would find useful. We decided to load only the parent table as XML, but before loading we removed invalid characters and blank rows. We were then able to apply an XSL Transform to produce the XHTML class list report sorted by surname (which appeared immediately after a space in the first column of rows that didn’t have a @class attribute):
<xsl:sort select="substring-after(td,' ')"/>
The final part of the solution was to provide staff with a list of course years for which class lists would be available. As class lists are only available where students have personal timetables, we asked for the student’s course code and name to be added to the view that indicated whether a student had a personal timetable. A SELECT DISTINCT on courses where there were students with individual timetables gave us the list we needed, which we included as an RSS feed to a staff-only page on timetabling’s intranet site.