2012-02-12 32 views
6

Tôi đang học xslt và có một câu hỏi về cách tôi có thể sử dụng biến xslt trong khác biệt. cho mỗi vòng lặp. Tôi biết xslt không phải là một ngôn ngữ thủ tục để biến được khai báo trong vòng lặp không thể được truy cập trong vòng lặp khác. Nhưng có cách nào tôi chỉ có thể khai báo biến toàn cầu sau đó gán một số giá trị trong lần đầu tiên cho vòng lặp và sử dụng biến đó trong thứ hai cho vòng lặp?phạm vi biến xslt và cách sử dụng nó

Bất kỳ ý tưởng nào cũng sẽ được đánh giá cao.

Cảm ơn

Trả lời

13

là có cách nào tôi có thể chỉ cần tuyên bố globa l biến sau đó gán một số giá trị đầu tiên cho vòng lặp và sử dụng biến đó trong thứ hai cho vòng lặp?

Cách để gán giá trị cho một xsl:variable (tất nhiên đây chỉ là khởi tạo) từ bên trong một xsl:for-each, là bao gồm các xsl:for-each trong cơ thể của biến.

Đây là một ví dụ hoàn chỉnh:

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

<xsl:template match="/*"> 
    <xsl:variable name="vMax"> 
     <xsl:for-each select="num"> 
     <xsl:sort data-type="number" order="descending"/> 

     <xsl:if test="position() = 1"> 
     <xsl:value-of select="."/> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:variable> 

    Values close to the maximum: 
<xsl:text/> 

     <xsl:for-each select="num"> 
     <xsl:if test="not($vMax - . > 3) "> 
     <xsl:value-of select="."/> 
     <xsl:text>&#xA;</xsl:text> 
     </xsl:if> 
     </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

Khi chuyển đổi này được áp dụng trên các tài liệu XML sau ...

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

... đầu tiên nó định nghĩa một biến vMax mà được giá trị của nó từ xsl:for-each chứa trong cơ thể của nó.

Sau đó, biến số vMax được sử dụng trong số xsl:for-each thứ hai để xuất tất cả các số được "đóng" vào mức tối đa được tính như vậy.

Các muốn, kết quả chính xác được sản xuất:

 Values close to the maximum: 
07 
08 
09 
10 

Nó cũng có thể để mô phỏng "chuyển nhượng" một biến với giá trị khác nhau bằng cách sử dụng một cách đệ quy gọi tên mẫu và vượt qua các "giá trị mới" làm tham số cho mẫu được gọi là.

Dưới đây là ví dụ hiển thị kỹ thuật này. Ở đây chúng tôi đang tính toán tối đa các giá trị, chứa trong các nút của một tập hợp nút. Mỗi lần chúng ta truy cập vào nút tiếp theo trong tập nút, giá trị cực đại hiện tại được so sánh với giá trị này và nếu cần thiết, giá trị tối đa mới sẽ trở thành giá trị của nút tiếp theo. Sau đó chúng tôi gọi cùng một mẫu đệ quy, đi qua như giá trị của tối đa hiện hành tối đa mới:

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

<xsl:template match="/*"> 
    <xsl:call-template name="max"> 
    <xsl:with-param name="pList" select="*"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="max"> 
    <xsl:param name="pMax" select="-99999999"/> 
    <xsl:param name="pList"/> 

    <xsl:choose> 
    <xsl:when test="$pList[1]"> 
     <xsl:variable name="vnewMax" select= 
     "$pMax * ($pMax >= $pList[1]) 
     + 
     $pList[1] * not($pMax >= $pList[1]) 
     "/> 

     <xsl:call-template name="max"> 
     <xsl:with-param name="pMax" select="$vnewMax"/> 
     <xsl:with-param name="pList" select="$pList[position() > 1]"/> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="$pMax"/> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

Khi chuyển đổi này được áp dụng cho cùng một tài liệu XML (ở trên), các mong muốn, kết quả chính xác được sản xuất :

10 
+0

Vì vậy, làm thế nào tôi sẽ nhận được giá trị của hai lĩnh vực khác nhau để sử dụng sau này? – Julian

+0

Chỉ cần xác định hai biến và khởi tạo từng biến cho trường "tương ứng". Về "sau" - không có thứ gì trong ngôn ngữ chức năng. Việc đánh giá có thể xảy ra theo bất kỳ thứ tự nào và/hoặc song song –

0

xsl:for-each không phải là một vòng lặp theo nghĩa for hoặc foreach vòng tồn tại trong ngôn ngữ thủ tục vì vậy bất kỳ câu hỏi nói về vòng là khó hiểu và khó khăn hơn để trả lời.

Nếu bạn muốn sử dụng biến toàn cầu trong XSLT, bạn có thể làm như vậy nhưng bạn sẽ ràng buộc một giá trị cho biến mà bạn khai báo nó (tức là trên toàn cầu), bạn không thể gán giá trị sau này trong for-each muốn làm.

0
  1. bạn đã viết, 'XSL là một ngôn ngữ thủ tục' .. Vâng, không. Đây là Ngôn ngữ khai báo ..
  2. Biến được gán cùng với tuyên bố của nó, biến không thay đổi!
  3. Thông thường chúng ta làm theo cuộc gọi đệ quy cho các mẫu sử dụng call-template qua params cho họ .. (làm việc này như hàm đệ quy gọi với đối số qua các ngôn ngữ thủ tục)
    Đó là một phương pháp để xử lý tội và có điều kiện vòng lặp vv ..

Chúng tôi sẽ được hạnh phúc để giúp bạn trong trường hợp nếu bạn đề cập đến kịch bản chính xác với mẫu XML, và đầu ra bạn đang mong đợi ra khỏi nó :)

+0

biết đó là 3 năm trước nhưng ông đã viết * tôi biết XSLT không phải là một ngôn ngữ thủ tục * ... – LuckyLikey

+1

@LuckyLikey, rà soát chỉnh sửa lịch sử của câu hỏi, Dimitri đã sửa chữa nó. Trước đó nó là "Tôi biết XSLT là một ngôn ngữ thủ tục" –

+0

bạn phải .. im xin lỗi có được một +1 – LuckyLikey

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