XSLT将列中的信息添加到HTML表而不是行

时间:2014-11-16 12:46:56

标签: html xml xslt html-table

我已经获得了这个XML代码,我应该将其转换为传统的HTML时间表,在顶行显示日期名称,在右侧显示时间。当我尝试每次写行时,对我来说变得非常棘手。顺便说一下,不要考虑属性优先级。有人可以帮我这个吗?

<?xml version="1.0" encoding="ISO-8859-1"?>
<timetable>
   <day>
      <numday>1</numday>
      <task priority="medium">
          <time-sta>12</time-sta>
          <time-end>14</time-end>
          <name>Tutorías</name>
      </task>
   </day>
   <day>
       <numday>2</numday>
       <task priority="high">
           <time-sta>12</time-sta>
           <time-end>14</time-end>
           <name>Autómatas</name>
       </task>
   </day>
   <day>
       <numday>4</numday>
       <task priority="high">
           <time-sta>9</time-sta>
           <time-end>11</time-end>
           <name>Procesadores de lenguajes</name>
       </task>
       <task>
           <time-sta>16</time-sta>
           <time-end>17</time-end>
           <name>Matemática Discreta </name>
       </task>
   </day>
   <day>
       <numday>3</numday>
       <task priority="high">
           <time-sta>9</time-sta>
           <time-end>11</time-end>
           <name>Procesadores de lenguajes</name>
       </task>
   </day>
   <day>
       <numday>5</numday>
       <task priority="low">
           <time-sta>17</time-sta>
           <time-end>18</time-end>
           <name>Ver la tele</name>
       </task>
   </day>
</timetable>

如果可能,所需的输出应该是下一个html表:

<table>
    <tr>
        <th>Time/Day</th>
        <th>Monday</th>
        <th>Tuesday</th>
        <th>Wednesday</th>
        <th>Thursday</th>
        <th>Friday</th>
    </tr>
    <tr>
        <td>9:00 - 10:00</td>
        <td></td>
        <td></td>
        <td rowspan="2">Procesadores de lenguajes</td>
        <td rowspan="2">Procesadores de lenguajes</td>
        <td></td>
    </tr>
    <tr>
        <td>10:00 - 11:00</td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td>11:00 - 12:00</td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td>12:00 - 13:00</td>
        <td rowspan="2">Tutorías</td>
        <td rowspan="2">Autómatas</td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td>13:00 - 14:00</td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td>14:00 - 15:00</td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td>15:00 - 16:00</td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td>16:00 - 17:00</td>
        <td></td>
        <td></td>
        <td></td>
        <td>Matemática Discreta</td>
        <td></td>
    </tr>
    <tr>
        <td>17:00 - 18:00</td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td>Ver la tele</td>
    </tr>
</table>

是否可以使用xml获得该输出,或者是否需要每个节点至少具有用于定义时间表中所有时间段的标记,即使它们是空的?

1 个答案:

答案 0 :(得分:1)

嗯,这不是很简单。基于两个常量(9小时乘5天)生成表格相当简单。查找属于每个单元格的任务也不是太困难 - 您只需要将当前单元格的列和行与任务的一天和开始时间相匹配。棘手的部分是跳过前一个任务在前一个任务溢出到后续时隙的冗余单元格。

以下样式表:

XSLT 1.0

<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:key name="task" match="task" use="concat(../numday, '|', time-sta)" />
<xsl:key name="task-by-day" match="task" use="../numday" />

<xsl:template match="/">
    <table border="1">
        <tr>
            <th>Time/Day</th>
            <th>Monday</th>
            <th>Tuesday</th>
            <th>Wednesday</th>
            <th>Thursday</th>
            <th>Friday</th>
        </tr>
        <xsl:call-template name="rows">
            <xsl:with-param name="start-row" select="9"/>
            <xsl:with-param name="end-row" select="17"/>
        </xsl:call-template>
    </table>
</xsl:template>

<xsl:template name="rows">
    <xsl:param name="start-row"/>
    <xsl:param name="end-row"/>

        <tr>
            <th><xsl:value-of select="$start-row"/></th>
            <xsl:call-template name="cols">
                <xsl:with-param name="current-row" select="$start-row"/>
                <xsl:with-param name="start-col" select="1"/>
                <xsl:with-param name="end-col" select="5"/>
            </xsl:call-template>
        </tr>
        <!-- recursive call -->
        <xsl:if test="$start-row &lt; $end-row">
            <xsl:call-template name="rows">
                <xsl:with-param name="start-row" select="$start-row + 1"/>
                <xsl:with-param name="end-row" select="$end-row"/>
            </xsl:call-template>
        </xsl:if>
</xsl:template>

<xsl:template name="cols">
    <xsl:param name="current-row"/>
    <xsl:param name="start-col"/>
    <xsl:param name="end-col"/>

    <xsl:variable name="task" select="key('task', concat($start-col, '|', $current-row))" />
    <xsl:variable name="overlap-tasks" select="key('task-by-day', $start-col)[time-sta &lt; $current-row and time-end > $current-row]" />

    <xsl:if test="not($overlap-tasks)">
        <td rowspan="{$task/time-end - $task/time-sta}">
            <xsl:value-of select="$task/name"/>
        </td>
    </xsl:if>
    <!-- recursive call -->
    <xsl:if test="$start-col &lt; $end-col">
        <xsl:call-template name="cols">
            <xsl:with-param name="current-row" select="$current-row"/>
            <xsl:with-param name="start-col" select="$start-col + 1"/>
            <xsl:with-param name="end-col" select="$end-col"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入时,将返回:

<?xml version="1.0" encoding="UTF-8"?>
<table border="1">
  <tr>
    <th>Time/Day</th>
    <th>Monday</th>
    <th>Tuesday</th>
    <th>Wednesday</th>
    <th>Thursday</th>
    <th>Friday</th>
  </tr>
  <tr>
    <th>9</th>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="2">Procesadores de lenguajes</td>
    <td rowspan="2">Procesadores de lenguajes</td>
    <td rowspan="NaN"></td>
  </tr>
  <tr>
    <th>10</th>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
  </tr>
  <tr>
    <th>11</th>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
  </tr>
  <tr>
    <th>12</th>
    <td rowspan="2">Tutorías</td>
    <td rowspan="2">Autómatas</td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
  </tr>
  <tr>
    <th>13</th>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
  </tr>
  <tr>
    <th>14</th>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
  </tr>
  <tr>
    <th>15</th>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
  </tr>
  <tr>
    <th>16</th>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="1">Matemática Discreta </td>
    <td rowspan="NaN"></td>
  </tr>
  <tr>
    <th>17</th>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="NaN"></td>
    <td rowspan="1">Ver la tele</td>
  </tr>
</table>

呈现为:

enter image description here