2010-07-15 39 views
8

Tôi đã một bảng html viết bằng chuyển đổi XSLT trông như thế nàyXSLT cách tạo kiểu có điều kiện chẵn/lẻ hàng

<table> 
    <xsl:for-each select="someNode"> 
     <xsl:if test="testThis"> 
      <tr> 
       <!-- <xsl:call-template name="conditionalRowStyle"/> --> 
       <td>something</td> 
      </tr> 
     </xsl:if> 
     <tr> 
      <!-- <xsl:call-template name="conditionalRowStyle"/> --> 
      <td>this is always displayed</td> 
     </tr> 
     <xsl:if test="testThis2"> 
      <tr> 
       <!-- <xsl:call-template name="conditionalRowStyle"/> --> 
       <td>something 2</td> 
      </tr> 
     </xsl:if> 
     .... 
    </xsl:for-each> 
    <tr> 
     <!-- <xsl:call-template name="conditionalRowStyle"/> --> 
     <td>this is always displayed</td> 
    </tr> 
</table> 

Tôi cần một cách để áp dụng các lớp học khác nhau oddRow/evenRow để tr elems.

<tr class="evenRow"> or <tr class="oddRow"> 

Tôi cố gắng để sử dụng một mẫu như thế này sau mỗi <tr> elem

<xsl:template name="conditionalRowStyle"> 
    <xsl:attribute name="class"> 
     <xsl:choose> 
      <xsl:when test="(count(../preceding-sibling::tr) mod 2) = 0">oddrow</xsl:when> 
      <xsl:otherwise>evenrow</xsl:otherwise> 
     </xsl:choose> 
    </xsl:attribute> 
</xsl:template> 

nhưng điều này không làm việc. bất kỳ ý tưởng nào?

+0

Câu hỏi hay (+1). Xem câu trả lời của tôi cho một giải pháp XSLT 1.0 một lần :) –

Trả lời

17

Bạn có thể có thể nhận được ngay với làm điều này trong just css

tr:nth-child(odd) { 
    /*...*/ 
} 
tr:nth-child(odd) { 
    /*...*/ 
} 

Nếu bạn không thể, bạn có thể làm một cái gì đó giống như

<xsl:attribute name="class"> 
    <xsl:choose> 
     <xsl:when test="(position() mod 2) != 1"> 
      <xsl:text>evenRow</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:text>oddRow</xsl:text> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:attribute> 

Lưu ý rằng tôi đã viết này trong hộp văn bản SO và có không thử nghiệm nó.

+0

Điều này sẽ không hoạt động, vì các nút được chọn là dữ liệu nguồn được sử dụng để xây dựng bảng chứ không phải bảng. – mdma

+0

Cảm ơn bạn đã kính trọng. Giải pháp của bạn sẽ không hoạt động. Tôi không thể sử dụng các thuộc tính css như trong các bảng khác, tôi cần phải lập trình in 2+ hàng cùng màu. test = "(position() mod 2)! = 1 ngắt khi tôi sử dụng if statement để hiển thị các hàng có điều kiện – mickthompson

0

Có vẻ như mẫu conditionalRowStyle để thêm kiểu vào bảng nằm trong cùng một biểu định kiểu giống như bảng dựng bảng. Nếu trường hợp đó xảy ra, thì nó sẽ không hoạt động như mong đợi, vì các nút được chọn trong mẫu conditionalRowStyle sẽ từ tài liệu nguồn (có chứa someNode) và không phải là tài liệu đích (nơi các thành phần bảng được tạo ra.)

Bạn có thể "hack" điều này bằng cách thu thập đầu ra bảng của các mẫu someNode thành biến đầu tiên, sau đó bạn có thể chạy mẫu conditionalRowStyle trước khi cuối cùng xuất ra giá trị biến do kết quả của biểu định kiểu. Nhưng nó đơn giản hơn nhiều để sử dụng hai bảng định kiểu, bạn chạy cái này sau cái kia trong một đường ống. Biểu định kiểu đầu tiên chuyển đổi dữ liệu someNode thành bảng và thứ hai áp dụng định dạng conditionalRowStyle cho bảng.

3

chuyển đổi này:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common" 
exclude-result-prefixes="ext"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="vrtfTrs"> 
    <tr> 
    <td>something</td> 
    </tr> 
    <tr> 
    <td>This is always displayed</td> 
    </tr> 
    <tr> 
    <td>something 2</td> 
    </tr> 
</xsl:variable> 

<xsl:variable name="vTrs" select="ext:node-set($vrtfTrs)/*"/> 

<xsl:template match="/nums"> 
    <html> 
    <table> 
     <xsl:apply-templates select="num[1]"/> 
    </table> 
    </html> 
</xsl:template> 

<xsl:template match="num"> 
    <xsl:param name="pCount" select="0"/> 

    <xsl:variable name="vTest1" select=". mod 4 = 1"/> 
    <xsl:variable name="vTest2" select=". mod 4 = 2"/> 

    <xsl:apply-templates select="$vTrs[1][$vTest1]"> 
    <xsl:with-param name="pCount" select="$pCount +1"/> 
    <xsl:with-param name="pnodevalue" select="."/> 
    </xsl:apply-templates> 

    <xsl:apply-templates select="$vTrs[2]"> 
    <xsl:with-param name="pCount" select="$pCount+$vTest1 +1"/> 
    <xsl:with-param name="pnodevalue" select="."/> 
    </xsl:apply-templates> 

    <xsl:apply-templates select="$vTrs[3][$vTest2]"> 
    <xsl:with-param name="pCount" select="$pCount+$vTest1 +2"/> 
    <xsl:with-param name="pnodevalue" select="."/> 
    </xsl:apply-templates> 

    <xsl:apply-templates select="following-sibling::*[1]"> 
    <xsl:with-param name="pCount" 
      select="$pCount+1+$vTest1+$vTest2"/> 
    <xsl:with-param name="pnodevalue" select="."/> 
    </xsl:apply-templates> 

    <xsl:if test="not(following-sibling::*)"> 
     <xsl:apply-templates select="$vTrs[2]"> 
     <xsl:with-param name="pCount" select="$pCount+1+$vTest1+$vTest2"/> 
     <xsl:with-param name="pnodevalue" select="."/> 
     </xsl:apply-templates> 
    </xsl:if> 
</xsl:template> 

<xsl:template match="tr"> 
    <xsl:param name="pCount"/> 
    <xsl:param name="pnodevalue"/> 

    <tr class="{concat(substring('even', 1 div ($pCount mod 2 = 0)), 
        substring('odd', 1 div ($pCount mod 2 = 1)) 
        )}"> 
    <xsl:comment>&lt;num><xsl:value-of select="$pnodevalue"/>&lt;/num></xsl:comment> 
    <xsl:copy-of select="node()"/> 
    </tr> 
</xsl:template> 
</xsl:stylesheet> 

khi áp dụng trên tài liệu XML này:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

tạo ra kết quả mong muốn:

<html> 
    <table> 
     <tr class="odd"> 
     <!--<num>01</num>--> 
     <td>something</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>01</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>02</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>02</num>--> 
     <td>something 2</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>03</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>04</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>05</num>--> 
     <td>something</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>05</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>06</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>06</num>--> 
     <td>something 2</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>07</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>08</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>09</num>--> 
     <td>something</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>09</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="odd"> 
     <!--<num>10</num>--> 
     <td>This is always displayed</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>10</num>--> 
     <td>something 2</td> 
     </tr> 
     <tr class="even"> 
     <!--<num>10</num>--> 
     <td>This is always displayed</td> 
     </tr> 
    </table> 
</html> 

Do lưu ý:

  1. Chúng tôi đang sử dụng traversal nhất hạt mịn và chế biến một tài liệu XML - nút bằng nút. Sau khi chuyển đổi nhận dạng, đây là mẫu thiết kế XSLT quan trọng thứ hai.

  2. Phần còn lại của các thủ thuật nhỏ không quan trọng là.

+0

+1 Tuyệt vời! Breaking đệ quy và đi tuần tự với trục sau ... –

+0

@Alejandro: Vâng, chúng ta cần nhớ đôi khi '' quá thô. –

+0

chọn đăng nhập lẻ, thậm chí là tuyệt vời. – kalyan

Các vấn đề liên quan