2013-10-31 166 views
6

我是XSLT(v1.0)中的新成員,我無法使用XSLT將複雜的XHTML錶轉換爲LaTeX。使用XSLT將XHTML錶轉換爲LaTeX

我的意思是當我說複雜的表格時,表格中列的行數不同。換句話說,tdcolspan

即(XHTML表)

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

我在做什麼的XSL文件是:

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

但正如你所看到的,這個代碼只適用於簡單的表格,沒有colspan屬性。代碼圍繞第一個tr循環,並且對於每個td,它寫入「c」。所以,在上面的例子中,它只會創建一個列表。

我想要做的就是計算td的數量,以及如果存在的話可以創建一個正確的表格,包含3列。

有誰知道如何做到這一點?提前致謝。

+1

這應該被要求對計算器(它有一個非常活躍的XSLT標籤)這不是一個TeX問題 –

回答

6

這在XSLT2中更容易,但您可以使用XSLT 1中的(//*)[position() &lt;= n]慣用法重複n次。我也定了你的TeX位:\bf已經廢棄了,因爲在後面LaTeX2e的在1993年發佈:-)


<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

非常感謝你!我試圖修復它幾天。 – Wagner