可以更改此XSL代码以填充HTML表格吗?

时间:2016-01-29 13:25:10

标签: xml xslt-1.0

我对昨天提供给我的问题有这么好的答案:

Selecting specific entries in a for-each loop?

由于打印页面的空间限制,我想在表格中布局数据。以下是Microsoft Expression Web中修改的示例:

Desired output

所以,我想采用我正在使用的当前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>

因此,决赛桌将有1,2或3列。

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

唯一的其他区别是:

  1. 第一列的行前缀为&#34;描述&#34;值。
  2. 会有一个标题行说明&#34;学校&#34; (硬编码文本)。除非只有一列,否则不需要这一行。
  3. 是否可以以任何方式调整这些模板以创建此修订后的输出?

    以下是一些要使用的修订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>
    

    这似乎运作良好。但我想要&#34;描述&#34;标签只在第一列,我无法解决如何从其他列中删除它:

    Remove additional description labels

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

              <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. 我不想添加&#34;描述&#34;对于第二或第三桌。

    3. 可以这样做吗?

2 个答案:

答案 0 :(得分:1)

我相信我会这样做:

<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>

结果(渲染)是:

enter image description here

答案 1 :(得分:1)

你已将此作为your previous question的延伸 - 我的第一个答案是对我在那里给出的答案的改编。然而,问题的性质发生了显着变化,我认为用新鲜的眼睛看待它可能会更好。

这个解决方案可能不像另一个那样“聪明” - 但对我而言似乎更直接。

<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>

此处的结果是单个表格,呈现方式为:

enter image description here