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.
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. –
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' –
Estaba planteando la pregunta para ver si alguien tenía algo archivado. Voy a agregar un código de muestra en breve. – Jeff