Displaying a timetable with XSLT

2019-07-07 05:17发布

I'm trying to display a university courses timetable using XSLT. My DTS looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT timetable (day,day,day,day,day,day,day)>
<!ELEMENT day (session)*>
<!ELEMENT session (begin,end,(course?))>
<!ELEMENT course (#PCDATA)>
<!ELEMENT begin (#PCDATA)>
<!ELEMENT end (#PCDATA)>

I want to display all the courses in a Day/Hour table that looks something like this (excuse the horrible design):

timetable

Trouble is, I want to do a for each clause, but just on regular numbers, not on parts of the xml. Is that possible with XSLT? For example, it would probably look something like this:

/* for each time = 8..17, do: */
    <xsl:for-each select="timetable/day">
        <xsl:value-of select="session[[begin&lt;/*time*/ or begin=/*time*/]/course" />
    </xsl:for-each>

标签: xml xslt xpath
4条回答
戒情不戒烟
2楼-- · 2019-07-07 05:37

You would require to have 2 for each loops. one to iterate over the days of week and one for the hours of the day. The hours of the day could be solved with XSLT 2.0 easily like this:

<xsl:for-each select="8 to 17">
   <!-- do your stuff -->
   <xsl:value-of select="." /> <!-- dot represents a number from the range -->
</xsl:fo-each>

See this for a complete coverage of sequences and ranges.

查看更多
神经病院院长
3楼-- · 2019-07-07 05:39

in XSLT 2.0:

<xsl:variable name="timetable" select="timetable">
<table>
  <thead>
     .. output the table heading ..
  </thead>
  <tbody>
    <xsl:for-each select="8 to 17">
    <tr>
      <xsl:variable name="hour" select="."/>
      <td><xsl:value-of select="$hour, '-', $hour+1"/></td>          
      <xsl:for-each select="$timetable/day">
        <td><xsl:value-of 
            select="session[begin lt $hour+1 and end gt $hour]/course"/>
        </td>
      </xsl:for-each>
    </xsl:for-each>
  </tbody>
</table> 

plus a bit of work on the formatting.

查看更多
别忘想泡老子
4楼-- · 2019-07-07 05:46

You can use recursion:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <html>

      <head>
        <style type="text/css">td{border:solid 1px black} table{border-collapse:collapse}</style>
      </head>

      <table>
        <xsl:call-template name="for">
          <xsl:with-param name="count" select="10"/>
        </xsl:call-template>
      </table>
    </html>
  </xsl:template>

  <xsl:template name="for">
    <xsl:param name="i" select="0"/>
    <xsl:param name="count"/>

    <xsl:if test="$i &lt; $count">
      <tr>
        <td>
          <xsl:value-of select="concat($i + 8, ':00 - ', $i + 9, ':00')"/>
        </td>
      </tr>

      <xsl:call-template name="for">
        <xsl:with-param name="i" select="$i + 1"/>
        <xsl:with-param name="count" select="$count"/>
      </xsl:call-template>
    </xsl:if>

  </xsl:template>

</xsl:stylesheet>

Output:

enter image description here

查看更多
贼婆χ
5楼-- · 2019-07-07 06:00

You can use recursion

<xsl:template name="for_i_from_8_to_17">
    <xsl:param name="i">8</xsl:param> <!-- initial value -->
    <!-- do what you have to do -->
    <xsl:if test="not($i = 17)">
        <xsl:call-template name="for_i_from_8_to_17">
            <xsl:with-param name="i">
        <xsl:value-of select="$i + 1">
        </xsl:with-param>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

(slightly adapted from xsl-list@mulberrytech.com)

查看更多
登录 后发表回答