2011-01-07 10 views
5

Estoy comprobando si alguien tiene un XSLT que transforma las tablas HTML en CALS. He encontrado mucho material yendo para otro lado (CALS to HTML), pero no de HTML. Pensé que alguien podría haber hecho esto antes, así que no tengo que reinventar la rueda. No estoy buscando una solución completa. Solo un punto de partidaHTML a tablas CALS?

Si estoy lo suficientemente lejos por mi cuenta, lo publicaré para referencia futura.

+1

Por favor, proporcione un pequeño ejemplo: 1. el (X) HTML. 2. El resultado deseado. Muchas personas, yo incluido, no sé qué es una tabla CALS. –

+1

Desde el último OASIS [spec] (http://www.oasis-open.org/specs/tm9901.html) parece que la transformación es principalmente 'tr' ->' row' y 'td' ->' entry' –

+0

Estaba planteando la pregunta para ver si alguien tenía algo archivado. Voy a agregar un código de muestra en breve. – Jeff

Respuesta

4

he llegado a una solución mucho más simple que lo que @Flack relacionado con:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:template match="tbody"> 
    <xsl:variable name="maxColumns"> 
     <xsl:for-each select="tr"> 
      <xsl:sort select="sum(td/@colspan) + count(td[not(@colspan)])" data-type="number"/> 
      <xsl:if test="position() = last()"> 
       <xsl:value-of select="sum(td/@colspan) + count(td[not(@colspan)])"/> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:variable> 
    <tgroup> 
     <xsl:attribute name="cols"> 
      <xsl:value-of select="$maxColumns"/> 
     </xsl:attribute> 
     <xsl:apply-templates select="@*|node()"/> 
    </tgroup> 
</xsl:template> 

<xsl:template match="td[@colspan > 1]"> 
    <entry> 
     <xsl:attribute name="namest"> 
      <xsl:value-of select="sum(preceding-sibling::td/@colspan) + count(preceding-sibling::td[not(@colspan)]) + 1"/> 
     </xsl:attribute> 
     <xsl:attribute name="nameend"> 
      <xsl:value-of select="sum(preceding-sibling::td/@colspan) + count(preceding-sibling::td[not(@colspan)]) + @colspan"/> 
     </xsl:attribute> 
     <xsl:apply-templates select="@*[name() != 'colspan']|node()"/> 
    </entry> 
</xsl:template> 

<xsl:template match="tr"> 
    <row> 
     <xsl:apply-templates select="@*|node()"/> 
    </row> 
</xsl:template> 

<xsl:template match="td"> 
    <entry> 
     <xsl:apply-templates select="@*|node()"/> 
    </entry> 
</xsl:template> 

<xsl:template match="td/@rowspan"> 
    <xsl:attribute name="morerows"> 
     <xsl:value-of select=". - 1"/> 
    </xsl:attribute> 
</xsl:template> 

<!-- fallback rule --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

Hay dos puntos difíciles. En primer lugar, una tabla CALS necesita un atributo tgroup/@ cols que contiene el número de columnas. Así que tenemos que encontrar el número máximo de celdas en una fila en la tabla XHTML, pero debemos prestar atención a las declaraciones colspan para que una celda con colspan > 1 cree el número correcto de columnas. La primera plantilla en mi hoja de estilos hace precisamente eso, basada en la respuesta de @Tim C al max cells per row problem.

Otro problema es que para las células de varias columnas XHTML dice "esta célula es de 3 columnas de ancho" (colspan = "3") mientras CALS dirán "esta célula comienza en la columna 2 y termina en la columna 4" (namest = "2" nameend = "4"). Esa transformación se realiza en la segunda plantilla en la hoja de estilo.

El resto es de hecho bastante sencillo. La hoja de estilos no trata detalles como cambiar style = "width: 50%" into width = "50%" etc. pero esos son problemas relativamente comunes, creo.

+0

¡Gracias por esto! Mi proyecto cambió y no tuve la oportunidad de volver a hacerlo. Definitivamente lo tendré en cuenta ya que sé que volverá a surgir. ¡Gracias! – Jeff

Cuestiones relacionadas