p2p.wrox.com Forums

p2p.wrox.com Forums (http://p2p.wrox.com/index.php)
-   XSLT (http://p2p.wrox.com/forumdisplay.php?f=86)
-   -   how to populate a table with xml data in xslt (http://p2p.wrox.com/showthread.php?t=58404)

miccipynewbie May 26th, 2007 06:18 PM

how to populate a table with xml data in xslt

im a newbie as my name suggests and ive been trying to populate a table for a time table.


 <university universityName="nottingham University">
 <campus campusName="Wisteria"/>
 <Semester semesterNumber="1"/>
 <student studentNumber="2321557">
   <module Crn="x73236">
     <moduleName>Enterprise Database Systems</moduleName>
   <st ID="s1">09:00 AM</st>
   <st ID="s2">09:30 AM</st>
   <st ID="s3">10:00 AM</st>
   <st ID="s4">10:30 AM</st>
   <st ID="s5">11:00 AM</st>
   <st ID="s6">11:30 AM</st>
   <et ID="e1">09:29 AM</et>
   <et ID="e2">09:59 AM</et>
   <et ID="e3">10:29 AM</et>
   <et ID="e4">10:59 AM</et>
   <et ID="e5">11:29 AM</et>
   <et ID="e6">11:59 AM</et>
   <et ID="e7">12:29 PM</et>
   <et ID="e8">12:59 PM</et>
 <building buildingName="COLLB">
   <buildingRoom roomId="collb1">C114</buildingRoom>
   <buildingRoom roomId="collb2">C120</buildingRoom>
   <buildingRoom roomId="collb3">C121</buildingRoom>
   <buildingRoom roomId="collb4">CG76</buildingRoom>
 <week weekNumber="124">
   <day dayOfWeek="Monday">
     <allocation allocationCrn="83488">
       <registeredModule moduleRef="x73245"/>
       <class classNumber="C01" classType="Lecture"/>
       <assignedRoom buildingRef="collb1"/>
       <starts startTimeRef="s1"/>
       <ends endTimeRef="e4"/>
     <allocation allocationCrn="83490">
       <registeredModule moduleRef="x73245"/>
       <class classNumber="L02" classType="Laboratory"/>
       <assignedRoom buildingRef="collb3"/>
       <starts startTimeRef="s4"/>
       <ends endTimeRef="e8"/>
  <day dayOfWeek="Tuesday"/>
  <day dayOfWeek="Wednesday"/>
  <day dayOfWeek="Thursday">
     <allocation allocationCrn="83476">
       <registeredModule moduleRef="x73236"/>
       <class classNumber="C01" classType="Lecture"/>
       <assignedRoom buildingRef="collb4"/>
       <starts startTimeRef="s5"/>
       <ends endTimeRef="e8"/>
  <day dayOfWeek="Friday">
     <allocation allocationCrn="83476">
       <registeredModule moduleRef="x73236"/>
       <class classNumber="L05" classType="Laboratory"/>
       <assignedRoom buildingRef="collb2"/>
       <starts startTimeRef="s3"/>
       <ends endTimeRef="e5"/>
  <day dayOfWeek="Saturday"/>
  <day dayOfWeek="Sunday"/>

so thats my basic gyst. there is obviously more than one week in a university calendar etc etc. now i need to make the weekly information in to a readable time table with the days on the x-axis as headers and the time on the y-axis. the university day starts at 9am and ends at 9pm (im only showing the abbreviated version). ive managed to get the header of the time table, and the times. but im so hopelessly lost with the populating of the table. PLEASE HELP[xx(]. ive tried tutorials but and i understand them but i have no idea how to apply the functions etc. the xslt is shown below.


<xsl:template match="/">
     <title>Student TimeTable</title>
     <xsl:call-template name="style"/>
     <div id="wrapper">
       <table border="1">
         <xsl:apply-templates select="timetable"/>

<xsl:template name="style">
 <style type="text/css">
     a:hover { background: #9fc; }
     .header { background: #ccc; }
     .activity { background: #ff9; }
     .small { font-size: 70%; }
     .link { font-size: 120%; font-family: sans-serif; }
     .note{font-size: x-small; font-weight:bold;}
     #wrapper {width:1200px;height:700px;}

<xsl:template match="timetable">
     <td colspan="3">Student Timetable</td>
     <td colspan="4"><xsl:apply-templates select="student"/></td>
     <td><xsl:apply-templates select="student/name"/></td>
     <td colspan="8" align="right"></td>           
     <td colspan="8">
       <p>Any modules shown at the bottom of the page with a
       zero after it is not timetabled.</p>
   <tr><td colspan="8"/></tr>
     <td colspan="8">
    <p>The current week is displayed by default. If this is not
        a teaching week you will need to click on Next Week or
        Previous Week to view the timetable.</p>
     <td colspan="8">
    Go to (DD/MM/YYYY):<input type="text" name="date"/>
                           <input type="submit" value="Submit"/>
     <td colspan="2"><a href="">Previous Week</a></td>
     <td colspan="4">Week Of 07 May 2007 (137 of 138)</td>
     <td colspan="2" align="right"><a href="">Next Week</a></td>
     <th class="header"/>
     <xsl:apply-templates select="week[1]/day" mode="header"/>
   <xsl:apply-templates select= "student/registeredModules/studentsModules"/>
   <xsl:apply-templates select ="startTime/st"/>

<xsl:template match="studentsModules">
   <td><a href=""><xsl:value-of select="text()"/>- 0</a></td>
<td>- <xsl:value-of select="../../../modules/module/moduleCrn"/></td>

<xsl:template match="student">
  <xsl:value-of select="@studentNumber"/>

<xsl:template match="name">
  <xsl:value-of select="."/>

<xsl:template match="day" mode="header">
 <th class="header">
   <xsl:value-of select="@dayOfWeek"/>

 <xsl:template match="st">
   <xsl:if test="position( ) mod 2 > 0">
     <tr class="header">
       <td><xsl:value-of select="text()"/></td>

please help. im baffled and flumoxed :D[:p]

mhkay May 27th, 2007 04:13 AM

Could you please try and produce a simplified version of the problem that captures the essence of where you are having difficulty? There's so much data here that's essentially irrelevant to the problem, and most of the code you've shown seems to be playing around the edges of it rather than attacking the core. You can add the frills later once you've got the basic structure right.

Showing the output you want to produce is always useful.

A couple of comments on your data: you should really be using ISO representations of dates and times; and your use of synthetic identifiers for each start and end time looks like relational normalization gone mad.

Michael Kay
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference

miccipynewbie May 27th, 2007 03:16 PM


i actually shortened all the code so il just show the simplified version of the XML and what i have done so far with the XSLT. i have no idea how to add the output i want to produce. ive never really used a forumn before. but basically i have to show a single week of timetable from monday to sunday and the corresponding lessons for each day.

what is iso representation?? sorry if thats a dumb question!!!! :)

mhkay May 27th, 2007 04:13 PM

ISO representation of dates is in the form YYYY-MM-DD, and times are HH:MM:SS. It's useful to use this format partly because it's an international standard, and partly because it's directly supported by the XSLT 2.0/XPath 2.0 function library when you need to compare, sort, format, or do computations on dates and times.

I'm afraid that "i have to show a single week of timetable from monday to sunday and the corresponding lessons for each day" doesn't give me enough to work with. A timetable for a course? For a student? For a room? What are the rows, what are the columns, and what goes in the cells?

Your input format uses time spans like:

       <starts startTimeRef="s3"/>
       <ends endTimeRef="e5"/>

One way to tackle this is to ignore the actual times that this represents and just translate it into a block that covers period 3, 4, and 5. In XSLT 2.0 that's

<xsl:variable name="periods" select="xs:integer(substring(starts/@startTimeRef,2,1)) to xs:integer(substring(ends/@endTimeRef,2,1))"/>

When you're writing the cell for period $N on a Monday, you can then enter a particular allocation $a in the cell if $a/../@dayOfWeek = 'Monday' and $a/(xs:integer(substring(starts/@startTimeRef,2,1)) to xs:integer(substring(ends/@endTimeRef,2,1))) = $N. (Remember that "=" tests for membership of a set).

Michael Kay
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference

miccipynewbie May 27th, 2007 05:39 PM

ah. okay. sorry for the silly questions. ok figured out a way to let you see what i would like the format to be like (took long enough)


thats all.

i saw what you meant by it would be helpful to see the intended output.

thanks again for the prompt replies...they are super super helpful.

mhkay May 27th, 2007 06:02 PM

I'm no HTML expert so I have to guess what the HTML code for that looks like: presumably what you have to do is along the lines

for-each time-slot
     for-each day-of-the-week
          if there's a session starting at this time/day
          then <td rowspan="length of session">
               apply-templates select="session"
          else if there's a session continuing at this time./day
          then ()
          else <td/>

which seems to translate into code something like the following. Im going to assume for simplification that the start and end times are labelled by numbers 1,2,3 rather than strings s1,s2, e1, e2:

<xsl:for-each select="startTime/st">
  <xsl:variable name="st" select="."/>
    <td><xsl:value-of select="."/></td>
    <xsl:for-each select="week[1]/day">
      <xsl:when test="allocation/starts[@startTimeRef=$st]">
         <xsl:variable name="alloc" select="allocation/starts[@startTimeRef=$st]"/>
         <xsl:variable name="length" select="$alloc/ends/@endTimeRef - $alloc/starts/@startTimeRef + 1"/>
         <td rowspan="{$length}">
            <xsl:apply-templates select="$alloc"/>
       <xsl:when test="alllocation[starts/@startTimeRef lt $st and ends/@endTimeRef ge $st]"/>

Michael Kay
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference

miccipynewbie May 28th, 2007 07:29 AM


was wondering, would it be better if i put the time allocations into the day and then assign each module to a specific starting time like so....

<week weekNumber="124">
  <day dayOfWeek="Monday">
    <timeOfDay start="8" time="12:30 AM"/>
    <timeOfDay start="9" time="1:00 PM">
      <allocated allocationRef="bis83488"/>
    <timeOfDay start="10" time="1:30 PM"/>

it makes sense right if i was making a tree diagram that a week has days, and days has times??

next question:D.....

should i assign attributes that act like boolean values to the times that have module allocations ie

<week weekNumber="124">
 <day dayOfWeek="Monday">
  <timeOfDay st="1" time="12:00 PM"
  <timeOfDay st="2" time="12:30 PM"/>
  <timeOfDay st="3" time="1:00 PM">
   <allocated allocationRef="bis83488" starts="True" ends="False"/>
  <timeOfDay start="4" time="1:30 PM"/>
  <timeOfDay start="5" time="2:00 PM"/>
  <timeOfDay start="6" time="2:30 PM">
   <allocated allocationRef="bis83488" starts="False" ends="True"/>
  <timeOfDay start="7" time="3:00 PM"/>
  <timeOfDay start="8" time="3:30 PM">
   <allocated allocationRef="bis83480" starts="True" ends="False"/>
  <timeOfDay start="9" time="4:00 PM"/>
  <timeOfDay start="10" time="4:30 PM"/>
   <allocated allocationRef="bis83480" starts="False" ends="True"/>

and then find some way to say that:

for-each time-slot
 for-each day-of-the-week
  if there's a session starting at this time/day where starts is True
   <td rowspan="length of session">
    apply-templates select="session"
   else <td/>

hope that made sense!!!:)


All times are GMT -4. The time now is 12:57 AM.

Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.