ตัวนับภายใน xsl: สำหรับแต่ละลูป


90

วิธีรับตัวนับภายใน xsl: สำหรับแต่ละลูปที่จะแสดงจำนวนองค์ประกอบปัจจุบันที่ประมวลผล
ตัวอย่างเช่น XML ต้นทางของฉันคือ

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

สิ่งที่อยากได้คือ:

<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 ที่จะแก้ไข:

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

คำถามคือจะเอาอะไรมาแทนที่ ???. มีคีย์เวิร์ดมาตรฐานหรือไม่หรือต้องประกาศตัวแปรและเพิ่มค่าในลูป?

เนื่องจากคำถามค่อนข้างยาวฉันจึงควรคาดหวังคำตอบหนึ่งบรรทัดหรือคำเดียว :)

คำตอบ:


143

position(). เช่น:

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

9
ทั้งหมดนี้ดีและสวยงามจนคุณต้องเพิ่มตัวกรองเช่น xsl: ถ้าอยู่ใน xsl: for-each จากนั้นตำแหน่ง () ไม่มีประโยชน์และคุณต้องมีตัวนับที่เหมาะสม
Mike Starov

4
@ Mike Stavrov นั่นไม่ใช่ส่วนหนึ่งของคำถาม! ไม่สามารถครอบคลุมทุกสถานการณ์
redsquare

@redsquare ถูกต้อง แค่เพิ่มสองเซ็นต์ของฉัน ฉันต้องเขียนฟังก์ชันส่วนขยาย XSL เพื่อแก้ไขสถานการณ์ที่อธิบายไว้ บางทีฉันควรถามคนที่นี่เกี่ยวกับวิธีแก้ปัญหาที่ดีกว่า
Mike Starov

2
@MikeStarov แล้วจะทำอย่างไรถ้ามีxsl:ifภายในxsl:for-each? "ตัวนับที่เหมาะสม" คืออะไร? คุณสามารถชี้ไปที่แหล่งข้อมูลได้หรือไม่?
ลาจาร์

@lajarre คุณเขียนฟังก์ชันส่วนขยายที่กำหนดเองเพื่อเรียกใช้จาก XSL คุณยังสามารถทำการประมวลผลสองรอบ ประมวลผลครั้งเดียวและบันทึกเป็น xsl: variable จากนั้นใช้เทมเพลตกับเนื้อหาตัวแปร xsl และเพิ่มหมายเลขโดยใช้ตำแหน่ง ()
Mike Starov

13

ลองแทรก<xsl:number format="1. "/><xsl:value-of select="."/><xsl:text>แทน ???.

สังเกต "1. " - นี่คือรูปแบบตัวเลข ข้อมูลเพิ่มเติม: ที่นี่


ขอบคุณที่อ่านแล้วน่าสนใจเช่นกันฉันอาจจะใช้แนวทางนั้นเมื่อจำเป็นต้องมีการจัดรูปแบบ
kristof

เวอร์ชัน XSLT 1.0:<xsl:number format="1. " value="position()"/>
jsuddsjr

10

ลอง:

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

แก้ไข - สมองหยุดอยู่ที่นั่นตำแหน่ง () ตรงไปตรงมามากขึ้น!


3
ยังคงมีประโยชน์โดยเฉพาะอย่างยิ่งหากคุณเลือกตามเกณฑ์อื่นที่ไม่ใช่ตำแหน่ง () +1
jsuddsjr

7

คุณยังสามารถเรียกใช้คำสั่งเงื่อนไขบน Postion () ซึ่งมีประโยชน์มากในหลาย ๆ สถานการณ์

สำหรับเช่น

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

2
สิ่งนี้จะล้มเหลวหากคุณมีตัวกรองเช่น xsl: sort เนื่องจากรายการแรกอาจไม่ใช่รายการแรกที่ประมวลผล
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>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.