Tabla XML a LaTeX
xslt (1)
Supongamos que tengo una tabla XML de la forma
<table>
<tr>
<td>First Name:</td>
<td>Bill Gates</td>
</tr>
<tr>
<td rowspan="2">Telephone:</td>
<td>555 77 854</td>
</tr>
<tr>
<td>555 77 855</td>
</tr>
</table>
que deseo convertir a LaTeX usando XSLT (robé este ejemplo en otro lugar). El resultado que quiero es
/documentclass{memoir}
/usepackage{multirow}
/begin{document}
/begin{tabular}{*{10}{c}}
First name & Bill Gates &//
/multirow{2}{*}{Telephone:}
& 555 77 854 &//
& 555 77 855 &
/end{tabular}
/end{document}
En su mayor parte, existe una buena correspondencia uno a uno entre los dos formatos de tabla. Por lo tanto, esto funciona bastante bien en su mayor parte:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes" encoding="UTF-8"/>
<xsl:template match="/">
/documentclass{memoir}
/usepackage{multirow}
/begin{document}
<xsl:apply-templates/>
/end{document}
</xsl:template>
<xsl:template match="table">
/begin{tabular}{*{10}{c}}
<xsl:apply-templates/>
/end{tabular}
</xsl:template>
<xsl:template match="tr">
<xsl:apply-templates />//
</xsl:template>
<xsl:template match="td[not(@rowspan) and not(@colspan)]">
<xsl:apply-templates/> &
</xsl:template>
<xsl:template match="td[not(@colspoan)]">
/multirow{<xsl:value-of select="@colspan"/>}{*}{<xsl:apply-templates/>} &
</xsl:template>
<xsl:template match="td[not(@rowspan)]">
/multicolumn{<xsl:value-of select="@colspan"/>}{l}{<xsl:apply-templates/>} &
</xsl:template>
<xsl:template match="td">
/multirow{<xsl:value-of select="@rowspan"/>}{*}{/multicolumn{<xsl:value-of select="@colspan"/>}}{l}{<xsl:apply-templates/>} &
</xsl:template>
</xsl:stylesheet>
El problema es el &
s (que se convierten en &
en la salida). En LaTeX, necesitas uno al principio de la tercera fila, donde está la celda expandida. Este no es el caso en la tabla XML. ¿Cómo puedo evitar este problema?
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="text"/>
<xsl:template match="/">
/documentclass{memoir}
/usepackage{multirow}
/begin{document}
<xsl:apply-templates/>
/end{document}
</xsl:template>
<xsl:template match="table">
<xsl:variable name="noc" select="max(tr/sum(td/(@colspan/number(.),1)[1]))"/>
<xsl:text>/begin{tabular}{*{</xsl:text>
<xsl:value-of select="$noc"/>
<xsl:text>}{l}} </xsl:text>
<xsl:apply-templates select="tr[1]">
<xsl:with-param name="rspans" select="for $i in 1 to xs:integer($noc) return 0"/>
</xsl:apply-templates>
<xsl:text>/end{tabular}</xsl:text>
</xsl:template>
<xsl:template match="tr">
<xsl:param name="rspans"/>
<xsl:text/>% [<xsl:value-of select="$rspans"/>]
<xsl:variable name="tr" select="."/>
<xsl:for-each select="$rspans">
<xsl:variable name="c" select="position()"/>
<xsl:variable name="td" select="$tr/td[count($rspans[position() <=$c][.=0])]"/>
<xsl:if test=".=0">
<xsl:if test="$td/@rowspan[. > 1]">
<xsl:text>/multirow{</xsl:text>
<xsl:value-of select="$td/@rowspan"/>
<xsl:text>}{*}{</xsl:text>
</xsl:if>
<xsl:apply-templates select="$td"/>
<xsl:if test="$td/@rowspan[. > 1]">}</xsl:if>
</xsl:if>
<xsl:choose>
<xsl:when test=". >1 and position()=last()">&// </xsl:when>
<xsl:when test="position()=last()">// </xsl:when>
<xsl:otherwise>&</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:apply-templates select="following-sibling::tr[1]">
<xsl:with-param name="rspans" select="for $c in 1 to count($rspans)
return
($rspans[$c] +
td[count($rspans[position() <=$c][.=0])]/(@rowspan,1)[1]
-1)"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>