Click to See Complete Forum and Search --> : Displaying a schedule


UofCRuss
01-06-2009, 10:51 AM
I have a quick question regarding XSL. I am currently working on a project that helps students schedule there university courses, the output (the scheduled courses) is provided in XML. What I want to do is take that XML and display it as a weekly schedule going from Monday to Sunday and 08:00 to 18:00.

My problem is I have 5 classes that could run anywhere from Monday to Sunday and from 08:00 to 18:00. How would I use XSL to display a weekly schedule? The only way I could think of doing it was to check if a class ran at 08:00 on monday if it did display the name, then check 08:30 on monday, 09:00 on monday...... 08:00 on sunday.... etc.

This method seem very long. Is there another way of doing this?

Here is the XML data that I get back from the scheduler (1 Class)

<course>
<faculty>ENEL</faculty>
<number>567</number>
<description>Cmos Vlsi Engineering </description>
<lecture>
<instructor>Karan Vir Inder Kaler</instructor>
<section>01</section>
<peoplesoft>18352</peoplesoft>
<days>
<monday>true</monday>
<tuesday>false</tuesday>
<wednesday>true</wednesday>
<thursday>false</thursday>
<friday>true</friday>
<saturday>false</saturday>
<sunday>false</sunday>
</days>
<stime>15:00</stime>
<etime>15:50</etime>
<location>ENA 227</location>
</lecture>

<tutorial>
<instructor>Karan Vir Inder Kaler</instructor>
<section>01</section>
<peoplesoft>18358</peoplesoft>
<days>
<monday>false</monday>
<tuesday>false</tuesday>
<wednesday>true</wednesday>
<thursday>false</thursday>
<friday>false</friday>
<saturday>false</saturday>
<sunday>false</sunday>
</days>
<stime>08:00</stime>
<etime>08:50</etime>
<location>ENA 227</location>
</tutorial>

<laboratory>
<instructor>Karan Vir Inder Kaler</instructor>
<section>01</section>
<peoplesoft>18354</peoplesoft>
<days>
<monday>false</monday>
<tuesday>false</tuesday>
<wednesday>true</wednesday>
<thursday>false</thursday>
<friday>false</friday>
<saturday>false</saturday>
<sunday>false</sunday>
</days>
<stime>09:00</stime>
<etime>11:50</etime>
<location>ICT 216</location>
</laboratory>
</course>

Scriptage
01-06-2009, 01:04 PM
Could you provide an HTML page with the desired output (formatting) please and I'll see what I can come up with.

UofCRuss
01-06-2009, 03:31 PM
Something like this

http://bttrgroup.u46.nozonenet.com/mediawiki-1.13.2/images/e/e1/Peoplesoft.png

UofCRuss
01-07-2009, 04:45 PM
Anyone have any idea on how to do this? seems stupid to check everyday and every time.

Thanks again!

jkmyoung
01-07-2009, 05:52 PM
There's about 4 or 5 things you need to do.

Create a base table layout.
- Create the top header rows

Define rows and columns
- Define the days
- Define the hours (integerwise)

xmlns:my="internal"
<my:mapping>
<days>
<day>monday</day>
<day>tuesday</day>
<day>wednesday</day>
<day>thursday</day>
<day>friday</day>
<day>saturday</day>
<day>sunday</day>
<days>
<hours>
<hour>8</hour>
<hour>9</hour>
<hour>10</hour>
<hour>11</hour>
<hour>12</hour>
<hour>13</hour>
<hour>14</hour>
<hour>15</hour>
</hours>
</my:mapping>


Map the start times to an easy integer.
<stime>15:00</stime>
xpath: substring(stime, 1,2)

Neat trick: Use document('') to reference nodes in your document.
First search rows (hour), then search columns (day). Make sure to keep a variable to store hours.

<xsl:variable name="origDoc" select="."/> <!-- important since we're changing contexts -->
<xsl:for-each select="document('')//hour">
<tr>
<th>
<xsl:choose>
<xsl:when test=". &lt; 13"><xsl:value-of select="concat(.,':00AM')"/></xsl:when>
<xsl:otherwise><xsl:value-of select="concat(.-12,'00PM')"/></xsl:when>
</xsl:choose>
</th>
<xsl:variable name="hour" select="."/><!-- store this value since we will be changing context with next for-each -->
<xsl:for-each select="day">
<td>
???CODE???
</td>
</xsl:for-each>
</xsl:for-each>


So what goes in the ???CODE??? section?
Find all classes which fit. Take this one step at a time.
Original Document - $origDoc
All Course nodes - $origDoc//course
All Course classes? (lab/tutorial etc.)
- $origDoc//course/*
All course nodes day indicators which match current day:
- $origDoc//course/*[days/*[local-name() = current()]]
Add a [.='true'] and we have it.
- $origDoc//course/*[days/*[local-name() = current()][.='true']]
Now add the hour restriction.
- $origDoc//course/*[days/*[local-name() = current()][.='true']][stime &lt;= hour and etime &gt; hour]
However stime and etime are not integers. so we'll have to change that.
- $origDoc//course/*[days/*[local-name() = current()][.='true']][substring(stime,1,2) &lt;= hour and substring(etime,1,2) + .01 * substring(etime, 4,2) &gt; hour]

Note the extra condition on etime, since if it ends at 12:00 we don't want to put it in the 12:00PM slot. However if it ends anywhere from 12:01-12;59, we will.

Have to go now, but hope you can make some headway with this.