是否可以更改此 XSL 代码以填充 HTML table?

Can this XSL code be changed to fill in a HTML table instead?

我对昨天提供给我的一个问题有了这个很好的答案:

由于打印页面上的 space 限制,我想将数据布局为 table。这是一个在 Microsoft Expression Web 中修改的示例:

所以,我想使用我当前使用的 XSL 代码:

<xsl:variable name="AssignHistory" select="document('AssignHistory.xml')"/>
<xsl:variable name="week" select="Date/@NextWeek"/>
<xsl:apply-templates select="$AssignHistory/AssignmentHistory/*[name()=$week]/StudentItems"/>

模板函数:

<xsl:template match="StudentItems">
  <xsl:apply-templates select="Item[not((position() - 1) mod 7)]" mode="leader"/>
</xsl:template>

<xsl:template match="Item" mode="leader">
  <xsl:value-of select="Description"/>
  :&#160;
  <xsl:value-of select="Name"/>
  <br/>
  <xsl:apply-templates select="following-sibling::Item[position() &lt;= 6 and position() mod 2]"/>
</xsl:template>

<xsl:template match="Item">
  <xsl:value-of select="Description"/>
  :&#160;
  <xsl:value-of select="Name"/>
  <xsl:apply-templates select="following-sibling::Item[1]" mode="follower"/>
  <br/>
</xsl:template>

<xsl:template match="Item" mode="follower">
  <xsl:text> / </xsl:text>
  <xsl:value-of select="Name"/>
</xsl:template>

所以,最后的 table 将有 1、2 或 3 列。

如果列表中有 7 项学生项目,则它有 1 列内容。 如果有 14 个项目,则第 7 到 14 项显示在第二列中。 如果有 21 项,则第 15 到 21 项显示在第三列中。

唯一的其他区别是:

  1. 第一列的行将以 "description" 值作为前缀。
  2. 会有一个标题行说明 "school"(硬编码文本)。除非只有 1 列,否则不需要这一行。

是否可以以任何方式调整这些模板以创建此修改后的输出?

这里是一些修改后的 XML 数据以供使用:

    <StudentItems>
        <Item>
            <Name Counsel="9">1</Name>
            <Type>Bible Reading (Main)</Type>
            <Description>Bible Reading</Description>
        </Item>
        <Item Description="Initial Call">
            <Name Counsel="37">2</Name>
            <Type>#1 Student (Main)</Type>
            <Description>Initial Call</Description>
        </Item>
        <Item>
            <Name>3</Name>
            <Type>Assistant</Type>
            <Description>Initial Call</Description>
        </Item>
        <Item>
            <Name Counsel="48">4</Name>
            <Type>#2 Student (Main)</Type>
            <Description>Return Visit</Description>
        </Item>
        <Item>
            <Name>5</Name>
            <Type>Assistant</Type>
            <Description>Return Visit</Description>
        </Item>
        <Item>
            <Name Counsel="27">6</Name>
            <Type>#3 Student (Main)</Type>
            <Description>Bible Study</Description>
        </Item>
        <Item>
            <Name>7</Name>
            <Type>Assistant</Type>
            <Description>Bible Study</Description>
        </Item>
    </StudentItems>

非常感谢您的帮助。我很感激。

我进步很大。不知道是不是最好的方法:

            <table cellpadding="2">
              <xsl:apply-templates select="$AssignHistory/AssignmentHistory/*[name()=$week]/StudentItems"/>
            </table>

      <xsl:template match="StudentItems">
        <xsl:if test="Item[position() = 1]">
          <xsl:if test="count(Item) = 14">
            <tr>
              <td>
                <b>Main</b>
              </td>
              <td>
                <b>Auxiliary Class 1</b>
              </td>
            </tr>

          </xsl:if>
          <xsl:if test="count(Item) = 21">
            <tr>
              <td>
                <b>Main</b>
              </td>
              <td>
                <b>Auxiliary Class 1</b>
              </td>
              <td>
                <b>Auxiliary Class 2</b>
              </td>
            </tr>
          </xsl:if>
        </xsl:if>
        <tr>
        <xsl:apply-templates select="Item[not((position() - 1) mod 7)]" mode="leader"/>
        </tr>
      </xsl:template>

      <xsl:template match="Item" mode="leader">
        <td>
          <b><xsl:value-of select="Description"/>:&#160;</b>
          <xsl:value-of select="Name"/>
          <br/>
          <xsl:apply-templates select="following-sibling::Item[position() &lt;= 6 and position() mod 2]"/>
        </td>
      </xsl:template>

      <xsl:template match="Item">
        <b><xsl:value-of select="Description"/>:&#160;</b>
        <xsl:value-of select="Name"/>
        <xsl:apply-templates select="following-sibling::Item[1]" mode="follower"/>
        <xsl:if test="position() != 3">
          <br/>
        </xsl:if>
      </xsl:template>

      <xsl:template match="Item" mode="follower">
        <xsl:text> / </xsl:text>
        <xsl:value-of select="Name"/>
      </xsl:template>

这似乎很有效。但我只想在第一列上使用 "description" 标签,但我不知道如何将其从其他列中删除:

我继续尝试并应用建议的内容(内联 tables)并且代码更简单:

          <xsl:template match="StudentItems">
            <xsl:apply-templates select="Item[not((position() - 1) mod 7)]" mode="leader"/>
          </xsl:template>

          <xsl:template match="Item" mode="leader">
            <table cellpadding="2" style="float:left;">
            <tr>
              <td>
                <xsl:choose>
                  <xsl:when test="position() = 1">Main </xsl:when>
                  <xsl:when test="position() = 2">Auxiliary Class 1 </xsl:when>
                  <xsl:otherwise>Auxiliary Class 2 </xsl:otherwise>
                </xsl:choose>
              </td>
            </tr>
            <tr>
              <td>
                <b>
                  <xsl:value-of select="Description"/>:&#160;
                </b>
                <xsl:value-of select="Name"/>
              </td>
            </tr>
            <xsl:apply-templates select="following-sibling::Item[position() &lt;= 6 and position() mod 2]"/>
            </table>   
          </xsl:template>

          <xsl:template match="Item">
            <tr>
              <td>
                <b>
                  <xsl:value-of select="Description"/>:&#160;
                </b>
                <xsl:value-of select="Name"/>
                <xsl:apply-templates select="following-sibling::Item[1]" mode="follower"/>
              </td>
            </tr>
          </xsl:template>

          <xsl:template match="Item" mode="follower">
            <xsl:text> / </xsl:text>
            <xsl:value-of select="Name"/>
          </xsl:template>

这看起来更简单。谢谢。但我还有两个问题:

  1. 如果 StudentItems 列表中只有 7 个项目(或更少),我不需要标题行。

  2. 我不想为第二个或第三个 table 添加 "descriptions"。

这可以做到吗?

我相信我会做这样的事情:

<xsl:template match="StudentItems">
    <table border="1" style="display:inline;">
        <tr>
            <td>&#160;</td>
        </tr>
        <xsl:for-each select="Item[contains('1,2,4,6', position())]">
            <tr>
                <th><xsl:value-of select="Description"/></th>
            </tr>
        </xsl:for-each>
    </table>
    <xsl:apply-templates select="Item[position()mod 7 = 1]" mode="leader"/>
</xsl:template>

<xsl:template match="Item" mode="leader">
    <table border="1" style="display:inline;">
        <tr>
            <th colspan="2">
                <xsl:choose>
                    <xsl:when test="position() = 1">Main </xsl:when>
                    <xsl:when test="position() = 2">Auxiliary Class 1 </xsl:when>
                    <xsl:otherwise>Auxiliary Class 2 </xsl:otherwise>
                </xsl:choose>
            </th>
        </tr>   
        <tr>
            <td colspan="2"><xsl:value-of select="Name"/></td>
        </tr>
        <xsl:apply-templates select="following-sibling::Item[position() &lt;= 6 and position() mod 2]"/>
    </table>
</xsl:template>

<xsl:template match="Item">
    <tr>
        <td><xsl:value-of select="Name"/></td>
        <xsl:apply-templates select="following-sibling::Item[1]" mode="follower"/>
    </tr>
</xsl:template>

<xsl:template match="Item" mode="follower">
    <td><xsl:value-of select="Name"/></td>
</xsl:template>

应用于以下测试输入:

<StudentItems>
   <Item>
      <Name>Name 1</Name>
      <Description>Bible Reading</Description>
   </Item>
   <Item>
      <Name>Name 2</Name>
      <Description>Initial Call</Description>
   </Item>
   <Item>
      <Name>Name 3</Name>
      <Description>Initial Call</Description>
   </Item>
   <Item>
      <Name>Name 4</Name>
      <Description>Return Visit</Description>
   </Item>
   <Item>
      <Name>Name 5</Name>
      <Description>Return Visit</Description>
   </Item>
   <Item>
      <Name>Name 6</Name>
      <Description>Bible Study</Description>
   </Item>
   <Item>
      <Name>Name 7</Name>
      <Description>Bible Study</Description>
   </Item>
   <Item>
      <Name>Name 8</Name>
      <Description>Bible Reading</Description>
   </Item>
   <Item>
      <Name>Name 9</Name>
      <Description>Initial Call</Description>
   </Item>
   <Item>
      <Name>Name 10</Name>
      <Description>Initial Call</Description>
   </Item>
   <Item>
      <Name>Name 11</Name>
      <Description>Return Visit</Description>
   </Item>
   <Item>
      <Name>Name 12</Name>
      <Description>Return Visit</Description>
   </Item>
   <Item>
      <Name>Name 13</Name>
      <Description>Bible Study</Description>
   </Item>
   <Item>
      <Name>Name 14</Name>
      <Description>Bible Study</Description>
   </Item>
   <Item>
      <Name>Name 15</Name>
      <Description>Bible Reading</Description>
   </Item>
   <Item>
      <Name>Name 16</Name>
      <Description>Initial Call</Description>
   </Item>
   <Item>
      <Name>Name 17</Name>
      <Description>Initial Call</Description>
   </Item>
   <Item>
      <Name>Name 18</Name>
      <Description>Return Visit</Description>
   </Item>
   <Item>
      <Name>Name 19</Name>
      <Description>Return Visit</Description>
   </Item>
   <Item>
      <Name>Name 20</Name>
      <Description>Bible Study</Description>
   </Item>
   <Item>
      <Name>Name 21</Name>
      <Description>Bible Study</Description>
   </Item>
</StudentItems>

结果(呈现)是:

您将此作为 的扩展提出 - 我的第一个答案是对我在那里给出的答案的改编。然而,问题的性质已经发生了显着变化,我认为用新的眼光来看待它可能会更好。

这个解决方案可能不像另一个 "clever" - 但对我来说它似乎更直接。

<xsl:template match="StudentItems">
    <table border="1" width="80%">
        <thead>
            <tr>
                <th/>
                <xsl:for-each select="Item[contains('|1|8|15|', concat('|', position(), '|'))]">
                    <th colspan="2">
                        <xsl:choose>
                            <xsl:when test="position() = 1">Main</xsl:when>
                            <xsl:when test="position() = 2">Auxiliary Class 1</xsl:when>
                            <xsl:when test="position() = 3">Auxiliary Class 2</xsl:when>
                        </xsl:choose>
                    </th>
                </xsl:for-each>
            </tr>
        </thead>
        <tbody>
            <tr>
                <th><xsl:value-of select="Item[1]/Description"/></th>
                <xsl:for-each select="Item[contains('|1|8|15|', concat('|', position(), '|'))]">
                    <td colspan="2"><xsl:value-of select="Name"/></td>
                </xsl:for-each>
            </tr>
            <tr>
                <th><xsl:value-of select="Item[2]/Description"/></th>
                <xsl:for-each select="Item[contains('|2|3|9|10|16|17|', concat('|', position(), '|'))]">
                    <td><xsl:value-of select="Name"/></td>
                </xsl:for-each>
            </tr>
            <tr>
                <th><xsl:value-of select="Item[4]/Description"/></th>
                <xsl:for-each select="Item[contains('|4|5|11|12|18|19|', concat('|', position(), '|'))]">
                    <td><xsl:value-of select="Name"/></td>
                </xsl:for-each>
            </tr>
            <tr>
                <th><xsl:value-of select="Item[6]/Description"/></th>
                <xsl:for-each select="Item[contains('|6|7|13|14|20|21|', concat('|', position(), '|'))]">
                    <td><xsl:value-of select="Name"/></td>
                </xsl:for-each>
            </tr>
        </tbody>
    </table>
</xsl:template>

这里的结果是table,呈现为: