2010-09-17 6 views
5

У меня проблема, когда таблица имеет 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> 
+0

Хороший вопрос (+1). См. Мой ответ для классического решения XSLT 1.0 для таких проблем. :) –

ответ

3

Это классический 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> 
1

Вот XSLT2 решение, использующее для-каждой-группы. Чтобы изменить количество элементов в таблице, измените делитель в атрибуте group-сосед. Протестировано в Oxygen/XML с помощью Saxon 9.2.

<?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. Используйте для каждой группы выбор смежных наборов, где результат «position() - 1 idiv 3» дает тот же результат. Для первых трех строк это возвращает 0; для следующих трех результат равен 1 и т. д. Дивизор контролирует, как много строк группируются в каждый набор.
  3. Для каждого набора сгенерируйте элемент таблицы, затем скопируйте все атрибуты исходной таблицы, а затем строку заголовка, затем используйте шаблон идентификации (в конце таблицы стилей), чтобы скопировать все строки.

Обратите внимание, что если бы у вас были вложенные таблицы внутри строк, вам нужно было бы немного изменить это, чтобы избежать того, чтобы шаблон таблицы соответствовал внутренним таблицам.

+0

+1 Хорошее решение XSLT 2.0. – 2010-09-18 00:07:15

0

Это 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> 

Edit: Компактный код.

Смежные вопросы