2010-09-17 31 views
5

Tengo un problema donde una tabla tiene cientos de filas. Causa un problema y debe dividirse en varias tablas más pequeñas con menos filas cada una.Dividir la tabla grande en varias tablas más pequeñas

Mi html también es válido xml.

¿Cómo puedo dividir la tabla cada x filas en una nueva tabla?

Y, ¿cómo puedo copiar el estilo de la tabla, y la primera fila (encabezado) en cada tabla siguiente.

Así que algo como esto

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

Se convierte en

<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

Buena pregunta (1). Vea mi respuesta para la clásica solución XSLT 1.0 para este tipo de problemas. :) –

Respuesta

3

Esta es la solución XSLT 1.0 clásica para este tipo de problemas:

<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

Aquí es una solución XSLT2 utilizando para-cada-grupo. Para cambiar el número de elementos por tabla, cambie el divisor en el atributo de grupo adyacente. Probado en Oxygen/XML con 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> 

Explicación:

  1. En la plantilla "tabla" Crear una variable para el nodo de tabla en sí, por lo que se puede copiar sus atributos más tarde, y una variable que contiene la primera fila para ser reutilizados como el encabezamiento.
  2. Utilice para cada grupo para seleccionar conjuntos adyacentes donde el resultado de "posición() - 1 idiv 3" da el mismo resultado. Para las primeras tres filas, esto devuelve 0; para los próximos tres, el resultado es 1, y así sucesivamente. El divisor controla cuántas filas se agrupan en cada conjunto.
  3. Para cada conjunto, genere un elemento de tabla, luego copie todos los atributos de la tabla original, seguido de la fila de encabezado, luego use la plantilla de identidad (al final de la hoja de estilo) para copiar todas las filas.

Tenga en cuenta que si tuviera tablas anidadas dentro de las filas, tendría que modificarlas ligeramente para evitar que la plantilla "tabla" coincida con las tablas internas.

+0

+1 Buena solución XSLT 2.0. –

0

Esta hoja de estilo 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> 

Salida:

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

Editar: Código compacto.

Cuestiones relacionadas