【问题标题】:Split large table into several smaller tables将大表拆分成几个小表
【发布时间】:2010-09-17 21:18:55
【问题描述】:

我有一个表有 100 行的问题。它会导致问题,需要拆分为几个较小的表,每个表的行数较少。

我的 html 也是有效的 xml。

如何将每 x 行的表格拆分为一个新表格?

而且,如何将表格样式和第一行(标题)复制到每个后续表格中。

像这样的

<table class="..." style="...">
   <tr>
       <td>head 1</td>
       <td>head 2</td>
   </tr>

   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>

   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>

   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>

   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>

   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>

   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>
<table>

变成

<table class="..." style="...">
   <tr>
       <td>head 1</td>
       <td>head 2</td>
   </tr>

   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>

   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>
</table>

<table class="..." style="...">
   <tr>
       <td>head 1</td>
       <td>head 2</td>
   </tr>

   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>

   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>
</table>

<table class="..." style="...">
   <tr>
       <td>head 1</td>
       <td>head 2</td>
   </tr>

   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>

</table>

<table class="..." style="...">
   <tr>
       <td>head 1</td>
       <td>head 2</td>
   </tr>
   <tr>
       <td>col1</td>
       <td>col2</td>
   </tr>
<table>

【问题讨论】:

  • 好问题 (+1)。对于此类问题,请参阅我对经典 XSLT 1.0 解决方案的回答。 :)

标签: xslt


【解决方案1】:

这是针对此类问题的经典 XSLT 1.0 解决方案

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:param name="prowLimit" select="12"/>

    <xsl:variable name="vTable" select="/*"/>

 <xsl:template match="node()|@*" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="tr">
  <xsl:if test="position() mod $prowLimit = 1">
    <table>
      <xsl:copy-of select="$vTable/@*"/>
      <xsl:copy-of select=
      ". | following-sibling::tr[not(position() > $prowLimit -1)]"/>
    </table>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

【讨论】:

    【解决方案2】:

    这是一个使用 for-each-group 的 XSLT2 解决方案。要更改每个表的项目数,请更改 group-adjacent 属性中的除数。使用 Saxon 9.2 在 Oxygen/XML 中测试。

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
      exclude-result-prefixes="xs xd"
      version="2.0">
      <xsl:output method="xml" indent="yes"/>
      <xsl:template match="table">
        <xsl:variable name="tblNode" select="."/>
        <xsl:variable name="header"  select="tr[1]"/>
        <xsl:for-each-group select="tr[position() > 1]" group-adjacent="(position()-1) idiv 3">
          <xsl:element name="table">
            <xsl:copy-of select="$tblNode/@*"/>
            <xsl:copy-of select="$header"/>
            <xsl:apply-templates select="current-group()"/>
          </xsl:element>
        </xsl:for-each-group>
      </xsl:template>
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
    </xsl:stylesheet>
    

    解释:

    1. 在“表”模板中为表节点本身创建一个变量,以便我们稍后复制它的属性,以及一个包含要重用作为表头的第一行的变量。
    2. 使用 for-each-group 选择相邻的集合,其中“position()-1 idiv 3”的结果给出相同的结果。对于前三行,返回 0;对于接下来的三个,结果为 1,依此类推。除数控制将多少行分组到每个集合中。
    3. 对于每个集合,生成一个表格元素,然后复制所有原始表格的属性,然后是标题行,然后使用标识模板(在样式表的末尾)复制所有行。

    请注意,如果您在行内有嵌套表,则必须稍微修改一下以避免“表”模板与内部表匹配。

    【讨论】:

      【解决方案3】:

      这个 XSLT 1.0 样式表:

      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
          <xsl:param name="pMaxRow" select="2"/>
          <xsl:template match="/">
              <html>
                  <xsl:apply-templates
                       select="table/tr[(position()-1) mod $pMaxRow = 1]"
                       mode="table"/>
              </html>
          </xsl:template>
          <xsl:template match="node()|@*" name="identity">
              <xsl:copy>
                  <xsl:apply-templates select="@*|node()"/>
              </xsl:copy>
          </xsl:template>
          <xsl:template match="tr" mode="table">
              <table>
                  <xsl:apply-templates select="../@*|../tr[1]|.|following-sibling::tr
                                                   [$pMaxRow > position()]"/>
              </table>
          </xsl:template>
      </xsl:stylesheet>
      

      输出:

      <html>
          <table class="..." style="...">
              <tr>
                  <td>head 1</td>
                  <td>head 2</td>
              </tr>
              <tr>
                  <td>col1</td>
                  <td>col2</td>
              </tr>
              <tr>
                  <td>col1</td>
                  <td>col2</td>
              </tr>
          </table>
          <table class="..." style="...">
              <tr>
                  <td>head 1</td>
                  <td>head 2</td>
              </tr>
              <tr>
                  <td>col1</td>
                  <td>col2</td>
              </tr>
              <tr>
                  <td>col1</td>
                  <td>col2</td>
              </tr>
          </table>
          <table class="..." style="...">
              <tr>
                  <td>head 1</td>
                  <td>head 2</td>
              </tr>
              <tr>
                  <td>col1</td>
                  <td>col2</td>
              </tr>
              <tr>
                  <td>col1</td>
                  <td>col2</td>
              </tr>
          </table>
      </html>
      

      编辑:压缩代码。

      【讨论】:

        猜你喜欢
        • 2012-08-18
        • 2013-08-06
        • 2018-05-31
        • 1970-01-01
        • 2016-04-12
        • 2012-07-12
        • 2020-05-06
        • 2011-09-14
        • 1970-01-01
        相关资源
        最近更新 更多