2010-03-01 67 views
0

@Oded:抱歉,我的論述一直不佳...我的輸入文檔具有這樣的片段:渲染的節點序列作爲M×N個表

<recordset name="resId" > 
<record n="0">example 1</record> 
<record n="1">example 2</record> 
<record n="2">example 1</record> 
.... 
<record n="N">example 1</record> 
</recordset> 

含有任意長的節點序列。屬性「n」報告序列中節點的順序。我需要在M(行)×N(列)表中排列該序列的輸出,我在這樣做時遇到了一些麻煩。我不能把模板

<xsl:template match="recordset"> 
    <table> 
     <xsl:apply-templates select="record"/> 
    </table> 
</xsl:template> 

的東西,如:

<xsl:template match="record"> 
<xsl:if test="@n mod 3 = 0"> 
    <tr> 
</xsl:if> 
........ 
<td><xsl:value-of select"something"></td> 

因爲代碼是無效的(我應該以某種方式模板結束重複) ,我必須把一些(可能太多了)信任存在的編號屬性。有人有提示嗎?謝謝!

+1

您需要發佈一些XML樣本,用XSL樣本和所需的輸出。從你的問題來看,問題不是很清楚。 – Oded 2010-03-01 13:13:02

回答

3

必須確保嵌套從未斷過。你想嵌套在輸出中的東西必須嵌套在XSLT中。

<xsl:variable name="perRow" select="3" /> 

<xsl:template match="recordset"> 
    <table> 
    <xsl:apply-templates 
     mode = "tr" 
     select = "record[position() mod $perRow = 1]" 
    /> 
    </table> 
</xsl:template> 

<xsl:template match="record" mode="tr"> 
    <tr> 
    <xsl:variable name="td" select=" 
     . | following-sibling::record[position() &lt; $perRow] 
    " /> 
    <xsl:apply-templates mode="td" select="$td" /> 
    <!-- fill up the last row --> 
    <xsl:if test="count($td) &lt; $perRow"> 
     <xsl:call-template name="filler"> 
     <xsl:with-param name="rest" select="$perRow - count($td)" /> 
     </xsl:call-template> 
    </xsl:if> 
    </tr> 
</xsl:template> 

<xsl:template match="record" mode="td"> 
    <td> 
    <xsl:value-of select="." /> 
    </td> 
</xsl:template> 

<xsl:template name="filler"> 
    <xsl:param name="rest" select="0" /> 
    <xsl:if test="$rest"> 
    <td /> 
    <xsl:call-template name="filler"> 
     <xsl:with-param name="rest" select="$rest - 1" /> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 
+0

偉大的解決方案。我在想,如果它仍然具有不同累積元素,例如變量工作:的而不是在這個例子中元素。我試圖去做,但卡住了。真的很感激任何幫助。謝謝! – DashaLuna 2010-06-08 09:58:46

+0

我正在使用msxsl處理器。我堅持試圖獲取$ td變量中的節點列表。它選擇當前節點(指定爲「」),但我無法弄清楚如何從$ packageElements變量正確電流之後制定以下所有節點。 – DashaLuna 2010-06-08 10:51:39

+0

@DashaLuna:在這些評論中沒有什麼可以(或應該)回答。我認爲最好單獨提一個問題,如果你喜歡,可以在這裏設置一個鏈接,並且顯示你到目前爲止的XML和XSLT。 – Tomalak 2010-06-08 11:57:13

0

在XSLT 1.0中,使用通用的n行模板。

與該行元素名作爲參數,則正每行的模板是不依賴於你的輸入或輸出格式。

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

    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="recordset"> 
    <table> 
     <xsl:call-template name="n-per-row"> 
     <xsl:with-param name="select" select="record" /> 
     <xsl:with-param name="row-size" select="2"/> 
     <xsl:with-param name="row-element" select="'tr'"/> 
     </xsl:call-template> 
    </table> 
    </xsl:template> 

    <xsl:template match="record"> 
    <xsl:copy-of select="."/> 
    </xsl:template> 

    <xsl:template name="n-per-row"> 
    <xsl:param name="select" /> 
    <xsl:param name="row-size" /> 
    <xsl:param name="row-element" /> 
    <xsl:param name="start"> 
     <xsl:text>1</xsl:text> 
    </xsl:param> 

    <xsl:variable name="count" select="count($select)" /> 
    <xsl:variable name="last-tmp" select="number($start) + number($row-size)" /> 
    <xsl:variable name="last"> 
     <xsl:choose> 
     <xsl:when test="$last-tmp &gt; $count"> 
      <xsl:value-of select="$count"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$last-tmp"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 

    <xsl:element name="{$row-element}"> 
     <xsl:apply-templates select="$select[position() &lt;= $last]"/> 
    </xsl:element> 

    <xsl:if test="count($select) &gt; $last"> 
     <xsl:call-template name="n-per-row"> 
     <xsl:with-param name="select" select="$select[position() &gt; $last]"/> 
     <xsl:with-param name="row-size" select="$row-size"/> 
     <xsl:with-param name="row-element" select="$row-element"/> 
     <xsl:with-param name="start" select="$start"/> 
     </xsl:call-template> 
    </xsl:if> 

    </xsl:template> 

</xsl:stylesheet> 
+0

@Lachlan:這個解決方案比真正需要更多的遞歸。 – Tomalak 2010-03-01 13:54:33

1

使用XSLT 2.0

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output indent="yes"/> 
    <xsl:param name="rows">3</xsl:param> 
    <xsl:template match="recordset"> 
     <table> 
      <xsl:for-each-group select="record" group-by="count(preceding-sibling::*) mod $rows "> 
       <xsl:value-of select="current-grouping-key()"/> 
       <tr> 
        <xsl:for-each select="current-group()"> 
         <td> 
          <xsl:apply-templates/> 
         </td> 
        </xsl:for-each> 
       </tr> 
      </xsl:for-each-group> 
     </table> 
    </xsl:template> 
</xsl:stylesheet>