Bộ đếm bên trong xsl: for-each loop


89

Cách lấy bộ đếm bên trong xsl: for-each loop sẽ phản ánh số phần tử hiện tại được xử lý.
Ví dụ: XML nguồn của tôi là

<books>
    <book>
        <title>The Unbearable Lightness of Being </title>
    </book>
    <book>
        <title>Narcissus and Goldmund</title>
    </book>
    <book>
        <title>Choke</title>
    </book>
</books>

Những gì tôi muốn nhận được là:

<newBooks>
    <newBook>
        <countNo>1</countNo>
        <title>The Unbearable Lightness of Being </title>
    </newBook>
    <newBook>
        <countNo>2</countNo>
        <title>Narcissus and Goldmund</title>
    </newBook>
    <newBook>
        <countNo>3</countNo>
        <title>Choke</title>
    </newBook>
</newBooks>

XSLT để sửa đổi:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <newBooks>
            <xsl:for-each select="books/book">
                <newBook>
                    <countNo>???</countNo>
                    <title>
                        <xsl:value-of select="title"/>
                    </title>
                </newBook>
            </xsl:for-each>
        </newBooks>
    </xsl:template>
</xsl:stylesheet>

Vậy câu hỏi đặt ra là phải đặt cái gì ở chỗ ???. Có bất kỳ từ khóa chuẩn nào không hay tôi chỉ cần khai báo một biến và tăng nó lên bên trong vòng lặp?

Vì câu hỏi khá dài, tôi có lẽ nên mong đợi câu trả lời một dòng hoặc một từ :)

Câu trả lời:


141

position(). VÍ DỤ:

<countNo><xsl:value-of select="position()" /></countNo>

9
Điều này hoàn toàn ổn cho đến khi bạn phải thêm một bộ lọc như xsl: if bên trong xsl: for-each. Khi đó vị trí () là USELESS và bạn cần bộ đếm thích hợp.
Mike Starov

4
@Mike Stavrov Đó không phải là một phần của câu hỏi! Không thể trang trải mọi tình huống
redsquare

@redsquare Đúng. Chỉ cần thêm hai xu của tôi. Tôi đã phải viết một hàm mở rộng XSL để giải quyết tình huống được mô tả của mình. Có lẽ tôi nên hỏi mọi người ở đây về các giải pháp tốt hơn.
Mike Starov

2
@MikeStarov sau đó làm thế nào để làm nếu có một xsl:ifbên trong xsl:for-each? "Bộ đếm thích hợp" là gì? Bạn có thể chỉ vào một số tài nguyên?
lajarre

@lajarre Bạn viết một hàm mở rộng tùy chỉnh để được gọi từ XSL. Bạn cũng có thể thực hiện hai lần xử lý vượt qua. Xử lý một lần và lưu vào xsl: variable. Sau đó, áp dụng các mẫu trên nội dung biến xsl và thêm đánh số bằng vị trí ()
Mike Starov 12/1213

13

Hãy thử chèn <xsl:number format="1. "/><xsl:value-of select="."/><xsl:text>vào vị trí của ???.

Lưu ý "1." - đây là định dạng số. Thông tin thêm: tại đây


Cảm ơn, đó là một chi thú vị như well.I lẽ sẽ sử dụng cách tiếp cận rằng khi một số định dạng được yêu cầu
Kristof

Phiên bản XSLT 1.0:<xsl:number format="1. " value="position()"/>
jsuddsjr

10

Thử:

<xsl:value-of select="count(preceding-sibling::*) + 1" />

Chỉnh sửa - đã bị đóng băng ở đó, vị trí () đơn giản hơn!


3
Vẫn có thể hữu ích, đặc biệt nếu bạn đang chọn dựa trên các tiêu chí khác với vị trí (). 1
jsuddsjr

7

Bạn cũng có thể chạy các câu lệnh điều kiện trên Postion (), điều này có thể thực sự hữu ích trong nhiều trường hợp.

ví dụ.

 <xsl:if test="(position( )) = 1">
     //Show header only once
    </xsl:if>

2
Việc này không thành công nếu bạn có bộ lọc như xsl: sort vì khi đó mục đầu tiên có thể không phải là mục đầu tiên được xử lý.
Alexis Wilke

5
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <newBooks>
                <xsl:for-each select="books/book">
                        <newBook>
                                <countNo><xsl:value-of select="position()"/></countNo>
                                <title>
                                        <xsl:value-of select="title"/>
                                </title>
                        </newBook>
                </xsl:for-each>
        </newBooks>
    </xsl:template>
</xsl:stylesheet>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.