Penghitung di dalam xsl: untuk setiap loop


90

Cara mendapatkan penghitung di dalam xsl: for-each loop yang akan mencerminkan jumlah elemen saat ini yang diproses.
Misalnya XML sumber saya

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

Yang ingin saya dapatkan adalah:

<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 yang akan dimodifikasi:

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

Jadi pertanyaannya adalah apa yang harus menggantikan ???. Apakah ada kata kunci standar atau apakah saya hanya harus mendeklarasikan variabel dan menambahkannya di dalam loop?

Karena pertanyaannya cukup panjang, saya mungkin mengharapkan satu baris atau satu kata jawaban :)

Jawaban:


142

position(). MISALNYA:

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

9
Ini semua bagus dan keren sampai Anda harus menambahkan filter seperti xsl: jika di dalam xsl Anda: untuk masing-masing. Maka posisi () TIDAK BERGUNA dan Anda membutuhkan penghitung yang tepat.
Mike Starov

4
@ Mike Stavrov Itu bukan bagian dari pertanyaan! Tidak dapat mencakup semua situasi
redsquare

@redquare Benar. Hanya menambahkan dua sen saya. Saya harus menulis fungsi ekstensi XSL untuk menyelesaikan situasi yang saya gambarkan. Mungkin saya harus bertanya kepada orang-orang di sini tentang solusi yang lebih baik.
Mike Starov

2
@MikeStarov lalu bagaimana melakukannya jika ada xsl:ifdi dalam xsl:for-each? Apa itu "counter yang tepat"? Bisakah Anda menunjukkan beberapa sumber?
lajarre

@lajarre Anda menulis fungsi ekstensi kustom untuk dipanggil dari XSL. Anda juga dapat melakukan pemrosesan dua lintasan. Proses sekali dan simpan ke xsl: variable. Kemudian terapkan templat pada konten variabel xsl dan tambahkan penomoran menggunakan posisi ()
Mike Starov

13

Coba masukkan <xsl:number format="1. "/><xsl:value-of select="."/><xsl:text> sebagai ganti ???.

Perhatikan "1." - ini adalah format angka. Info lebih lanjut: di sini


Terima kasih, itu bacaan yang menarik juga. Saya mungkin akan menggunakan pendekatan itu ketika beberapa pemformatan diperlukan
kristof

Versi XSLT 1.0:<xsl:number format="1. " value="position()"/>
jsuddsjr

10

Mencoba:

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

Edit - mengalami pembekuan otak di sana, posisi () lebih mudah!


3
Masih bisa berguna, terutama jika Anda memilih berdasarkan kriteria selain posisi (). +1
jsuddsjr

7

Anda juga bisa menjalankan pernyataan bersyarat di Postion () yang bisa sangat membantu dalam banyak skenario.

untuk mis.

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

2
Ini gagal jika Anda memiliki filter seperti xsl: sort karena item pertama mungkin bukan yang pertama diproses.
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>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.