2012-03-07 22 views
6

Tôi gặp ít khó khăn trong việc gán biến số lượt truy cập và tăng biến đó và sau đó kiểm tra một giá trị nhất định trong XSLT. Đây là mã của tôi:Tăng và kiểm tra biến số lượt truy cập trong XSLT

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" <xsl:variable name="empty_string"/> 
    <xsl:variable name="counter" select="0"/> 
<xsl:template match="/Collection"> 
     <xsl:for-each select="Content"> 
      <xsl:sort select="Html/root/Event/start_date" order="ascending"/> 
<xsl:variable name="isFutureEvent"> 
         <xsl:value-of select="syscom:isFutureDate(Html/root/Event/start_date)" /> 
        </xsl:variable> 

        <xsl:if test="Html/root/Event != $empty_string"> 
         <xsl:if test="$isFutureEvent='true'"> 
          <!-- Increment Counter --> 
          <xsl:value-of select="$counter + 1"/> 
          <!-- Test if Counter < 4 --> 
          <xsl:if test="$counter &lt; 3"> 
          <div class="media"> 
          <!-- Do stuff here --> 
         </div> 
          </xsl:if> <!-- End if for counter --> 
         </xsl:if> 
        </xsl:if> 
       <!--</xsl:when>--> 
      <!--</xsl:choose>--> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

Nhưng dường như không tăng bộ đếm của tôi và không thoát khi bộ đếm truy cập 3. Mọi trợ giúp về điều này?

Trả lời

11

'Biến' trong XSL thực sự là hằng số - bạn không thể thay đổi giá trị của chúng. Đây:

<xsl:value-of select="$counter + 1"/> 

sẽ chỉ ra các giá trị của $counter+1

Để làm vòng bạn phải sử dụng đệ quy - ví dụ:

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

    <xsl:template name="loop"> 
    <xsl:param name="i"/> 
    <xsl:param name="limit"/> 
    <xsl:if test="$i &lt;= $limit"> 
     <div> 
     <xsl:value-of select="$i"/> 
     </div> 
     <xsl:call-template name="loop"> 
     <xsl:with-param name="i" select="$i+1"/> 
     <xsl:with-param name="limit" select="$limit"/> 
     </xsl:call-template> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="/"> 
    <html> 
     <body> 
     <xsl:call-template name="loop"> 
      <xsl:with-param name="i" select="0"/> 
      <xsl:with-param name="limit" select="10"/> 
     </xsl:call-template> 
     </body> 
    </html> 
    </xsl:template> 

</xsl:stylesheet> 

altough nó là tốt hơn để cố gắng tránh các vòng lặp - trong hầu hết các trường hợp XSL có thể được viết để tránh nó, nhưng tôi không hiểu đủ những gì bạn đang cố gắng đạt được để cung cấp cho bạn giải pháp hoàn chỉnh.

7

Tôi có cùng một vấn đề. Tôi cần giá trị gia tăng trong vòng lặp. Vì vậy, cách đơn giản nhất là bao gồm Saxon và sử dụng giá trị đó.

nếu bạn sử dụng Saxon 6.5.5

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
... 
xmlns:saxon="http://icl.com/saxon" 
extension-element-prefixes="saxon" 
version="3.0"> 

nếu bạn sử dụng Saxon 9.4.0.4

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
... 
xmlns:saxon="http://saxon.sf.net/" 
extension-element-prefixes="saxon" 
version="3.0"> 

Và sau đó bạn chỉ có thể sử dụng biến saxon:

<xsl:variable name="counter" select="0" saxon:assignable="yes"/> <!-- declare value --> 

<saxon:assign name="counter" select="$counter+1"/> <!-- increment value, you can do it in loop for example--> 

<xsl:value-of select="$counter"></xsl:value-of> <!-- print value --> 
+0

Thật không may, Saxon HE được giới hạn XSLT phiên bản 2.0, vì vậy bạn không thể sử dụng giải pháp này với phiên bản miễn phí . – Hraban

2

Trong trường hợp bất kỳ ai muốn làm điều này trong khi sử dụng .net (XslCompiledTransform), bạn có thể sử dụng

<xsl:stylesheet ... xmlns:customCode="urn:customCode"> 

<msxsl:script language="VB" implements-prefix="customCode"> 
    <![CDATA[ 
    private mCounter As Integer 
    Public Function AddToCounter() As Boolean 
     mCounter += 1 
     Return True 
    End Function 
    Public Function GetCounter() As Integer 
     Return mCounter 
    End Function 
    ]]> 
</msxsl:script> 

Sau đó, bạn thêm một cuộc gọi đến "customCode: AddToCounter()", và sau đó bạn có thể viết một thông điệp như thế này <xsl:message><xsl:value-of select="customCode:GetCounter()" /> rows remaining.</xsl:message>

+0

Câu trả lời hay, chỉ được sử dụng trong bản đồ xslt cho BizTalk – basvo

1

Chúng tôi không thể cập nhật xsl:variable khi họ cũng giống như hằng số. Nhưng chúng tôi có thể cập nhật dp:local-variables, vì vậy ở đây dp:local-variable bộ đếm được khởi tạo trước khi bắt đầu vòng lặp. Mỗi vòng lặp thời gian là đi ngược lại sẽ cập nhật chính nó bằng 1. Hãy thử này:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" <xsl:variable name="empty_string"/> 
    <xsl:template match="/Collection"> 
     <dp:set-local-variable name="'counter'" value="0"/> 
     <xsl:for-each select="Content"> 
      <dp:set-local-variable name="'counter'" value="dp:local-variable('counter')+1"/> 
      <xsl:sort select="Html/root/Event/start_date" order="ascending"/> 
      <xsl:variable name="isFutureEvent"> 
       <xsl:value-of select="syscom:isFutureDate(Html/root/Event/start_date)" /> 
      </xsl:variable> 

      <xsl:if test="Html/root/Event != $empty_string"> 
       <xsl:if test="$isFutureEvent='true'"> 

        <xsl:value-of select="dp:local-variable('counter')"/> 
        <!-- Test if Counter < 4 --> 
        <xsl:if test="dp:local-variable('counter') &lt; 3"> 
         <div class="media"> 
          <!-- Do stuff here --> 
         </div> 
        </xsl:if> 
        <!-- End if for counter --> 
       </xsl:if> 
      </xsl:if> 
      <!--</xsl:when>--> 
      <!--</xsl:choose>--> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Có vẻ như không gian tên 'dp' là tham chiếu đến IBM DataPower ... mà bạn không có tham chiếu đến trong trang tính của mình. Ngoài ra, thẻ biểu định kiểu của bạn không bị đóng. Ngay cả khi thẻ biểu định kiểu được sửa, tôi giả sử 'dp' sẽ không hoạt động nếu không nhập vùng tên hoặc chạy trên thiết bị IBM ...? –

0

Nếu bạn muốn biết bạn đang ở đâu trong một cho-mỗi vòng lặp, bạn có thể sử dụng vị trí built-in (chức năng).

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/Collection"> 
     <xsl:for-each select="Content"> 
      <xsl:if test="position() &lt; 3"> 
       <!-- Do this for nodes 1, 2 and 3 --> 
      </xsl:if> 
      <!-- Do this for every node --> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 
0

Trong trường hợp của tôi, tôi cần tổng hộp trong lô hàng, điều này giúp

<xsl:for-each select="ShippingConfirmation/Details/LicensePlates/LicensePlate"> 
      <xsl:if test="position()=last()"> 
       <xsl:value-of select="position()"/> 
      </xsl:if> 
    </xsl:for-each> 
Các vấn đề liên quan