2013-10-31 6 views
6

Ich bin neu in XSLT (v1.0) und ich kann nicht komplexe XHTML-Tabellen mit XSLT zu LaTeX konvertieren.Konvertieren von XHTML-Tabelle zu LaTeX mit XSLT

Was ich meine, wenn ich komplexe Tabellen sagte, sind Tabellen mit Zeilen mit unterschiedlicher Anzahl von Spalten. Mit anderen Worten, td mit colspan.

dh (xhtml Tabelle)

<table border="1" cellspacing="0" cellpadding="0"> 
    <tr> 
     <td valign="top" width="68" colspan="3"> <p>Values</p> </td> 
    </tr> 
    <tr> 
     <td valign="top" width="68"> <p>95</p> </td> 
     <td valign="top" width="68"> <p>169</p> <p> </p> </td> 
     <td valign="top" width="68"> <p>180</p> <p> </p> </td> 
    </tr> 
</table> 

Was ich in der XSL-Datei zu tun ist:

<xsl:template match="xhtml:table[@border='1']"> 
    <xsl:text>\begin{center}</xsl:text> 
    <xsl:text>\begin{tabular}{</xsl:text> 

    <xsl:for-each select="xhtml:tr[1]/*"> 
     <xsl:text>c</xsl:text> 
     <xsl:if test="position() = last()"> 
      <xsl:text>}&#10;</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 

    <xsl:text>\toprule&#10;</xsl:text> 
    <xsl:for-each select="xhtml:tr"> 
     <xsl:if test="position() != 1"> 
      <xsl:text>\midrule&#10;</xsl:text> 
     </xsl:if> 

     <xsl:if test="position() = 2"> 
      <xsl:text>\midrule&#10;</xsl:text> 
     </xsl:if> 

     <xsl:for-each select="xhtml:td|xhtml:th"> 
      <xsl:if test="name() = 'th'">{\bf </xsl:if> 
      <xsl:apply-templates /> 
      <xsl:if test="name() = 'th'">}</xsl:if> 

      <xsl:if test="position() != last()"> 
      <xsl:text>&amp;</xsl:text> 
      </xsl:if> 
     </xsl:for-each> 

     <xsl:text> \\&#10;</xsl:text> 
    </xsl:for-each> 

    <xsl:text>\bottomrule&#10;</xsl:text> 

    <xsl:text>\end{tabular}&#10;</xsl:text> 
    <xsl:text>\end{center}&#10;</xsl:text> 
</xsl:template> 

Aber wie Sie sehen können, dieser Code funktioniert nur für einfache Tabellen, ohne die Colspan-Attribut Der Code umschlingt die erste tr und schreibt für jede td ein "c". Im obigen Fall wird nur eine Tabelle mit einer Spalte erstellt.

Was ich tun möchte, ist die Anzahl der td und die Anzahl der Colspans zählen, wenn es existiert, um eine richtige Tabelle mit 3 Spalten zu erstellen.

Weiß jemand, wie man das macht? Danke im Voraus.

+1

in im Jahr 1993 :-) veröffentlicht wurde als veraltet Das auf Stackoverflow gestellt werden sollten (welches ein sehr aktives XSLT-Tag hat) Es ist keine TeX-Frage –

Antwort

6

Dies ist einfacher in XSLT2, aber Sie können das (//*)[position() &lt;= n] Idiom in XSLT 1 n-mal iterieren. Ich TeX ein bisschen auch fixiert auf: \bf seit latex2e


<table xmlns="http://www.w3.org/1999/xhtml" 
    border="1" cellspacing="0" cellpadding="0"> 
    <tr> 
     <td valign="top" width="68" colspan="3"> <p>Values</p> </td> 
    </tr> 
    <tr> 
     <td valign="top" width="68"> <p>95</p> </td> 
     <td valign="top" width="68"> <p>169</p> <p> </p> </td> 
     <td valign="top" width="68"> <p>180</p> <p> </p> </td> 
    </tr> 
</table> 

<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:xhtml="http://www.w3.org/1999/xhtml"> 

<xsl:output method="text"/> 

<xsl:template match="xhtml:table[@border='1']"> 
<xsl:text>\begin{center}&#10;</xsl:text> 
<xsl:text>\begin{tabular}{</xsl:text> 

<xsl:for-each select="xhtml:tr[1]/*"> 
    <xsl:choose> 
    <xsl:when test="@colspan"> 
    <xsl:for-each select="(//*)[position()&lt;=current()/@colspan]">c</xsl:for-each> 
    </xsl:when> 
    <xsl:otherwise>c</xsl:otherwise> 
    </xsl:choose> 
</xsl:for-each> 
<xsl:text>}&#10;</xsl:text> 

<xsl:text>\toprule&#10;</xsl:text> 
<xsl:for-each select="xhtml:tr"> 
    <xsl:if test="position() != 1"> 
    <xsl:text>\midrule&#10;</xsl:text> 
    </xsl:if> 

    <xsl:if test="position() = 2"> 
    <xsl:text>\midrule&#10;</xsl:text> 
    </xsl:if> 

    <xsl:for-each select="xhtml:td|xhtml:th"> 
    <xsl:if test="self::xhtml:th">\bfseries </xsl:if> 
    <xsl:apply-templates /> 
    <xsl:if test="position() != last()"> 
    <xsl:text>&amp;</xsl:text> 
    </xsl:if> 
    </xsl:for-each> 

    <xsl:if test="position()!=last()"> \\&#10;</xsl:if> 
</xsl:for-each> 

<xsl:text>\end{tabular}&#10;</xsl:text> 
<xsl:text>\end{center}</xsl:text> 

</xsl:template> 
</xsl:stylesheet> 

\begin{center} 
\begin{tabular}{ccc} 
\toprule 
Values \\ 
\midrule 
\midrule 
95 & 169 & 180 \end{tabular} 
\end{center} 
+0

vielen Dank! Ich habe versucht, es für einige Tage zu reparieren. – Wagner