[xsl] Hoe een variabele te gebruiken in node selectie?

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik wil een kleine image gallery bouwen met behulp van xsl. De image gallery biedt plaats aan maximaal 6 afbeeldingen, maar soms zijn het er minder. Ook als er geen afbeelding meer is wil ik een wit vlakje tonen met een grijze lijn eromheen. Hiervoor heb ik de volgende code geschreven:

XML:
1
2
3
4
5
6
<images>
  <image type="mainimage">1.jpg</image>
  <image>2.jpg</image>
  <image>3.jpg</image>
  <image>4.jpg</image>
</images>


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<xsl:template match="product">
    <xsl:call-template name="for.loop">
        <xsl:with-param name="i">1</xsl:with-param>
        <xsl:with-param name="count">6</xsl:with-param>
    </xsl:call-template>
</xsl:template>

<xsl:template name="for.loop">
    <xsl:param name="i"      />
    <xsl:param name="count"  />
    
    <div id="thumb">
        <xsl:if test="count(images/image)>=$i">
            <b><xsl:value-of select="$i" /></b><img src="{images/image[$i]}" />
        </xsl:if>
    </div>

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

</xsl:template>


De output van deze code van deze code is het volgende:

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
          <div id="thumb">
            <b>1</b>
            <img src="1.jpg" />
          </div>
          <div id="thumb">
            <b>2</b>
            <img src="1.jpg" />
          </div>
          <div id="thumb">
            <b>3</b>
            <img src="1.jpg" />
          </div>
          <div id="thumb">
            <b>4</b>
            <img src="1.jpg" />
          </div>
          <div id="thumb"></div>
          <div id="thumb"></div>
          <div id="thumb"></div>


Ik had graag gewild dat ie het volgende had geoutput:

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
          <div id="thumb">
            <b>1</b>
            <img src="1.jpg" />
          </div>
          <div id="thumb">
            <b>2</b>
            <img src="2.jpg" />
          </div>
          <div id="thumb">
            <b>3</b>
            <img src="3.jpg" />
          </div>
          <div id="thumb">
            <b>4</b>
            <img src="4.jpg" />
          </div>
          <div id="thumb"></div>
          <div id="thumb"></div>
          <div id="thumb"></div>


Wat doe ik mis? Op één of ander manier werkt dit stukje dus niet goed:

<img src="{images/image[$i]}" />

Acties:
  • 0 Henk 'm!

  • foliant
  • Registratie: Juli 2007
  • Laatst online: 19-01-2022
Je probeert nu de images als een soort array aan te roepen binnen Xslt,
tussen de rechte haken staat echter een conditie.

1,2,3,4 is allemaal waar en dus krijg je het eerste plaatje terug.

Vervang:
XML:
1
<img src="{images/image[$i]}" />

Door:
XML:
1
<img src="{images/image[position() = $i]}" />


xslt wijkt nogal af van programmeertalen als php, dit is waarom veel mensen het zo moeilijk vinden.

Acties:
  • 0 Henk 'm!

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

Daarnaast heb je die recursieve template aanroep ook helemaal niet nodig. Een simpele <xsl:for is voldoende :)

Daarnaast vind ik count(images/image)>=$i in combinatie met <xsl:if test="$i <= $count"> en de recursieve aanroep nogal omslachtig ;)

Sundown Circus


Acties:
  • 0 Henk 'm!

  • foliant
  • Registratie: Juli 2007
  • Laatst online: 19-01-2022
RedRose schreef op vrijdag 13 november 2009 @ 12:46:
Daarnaast heb je die recursieve template aanroep ook helemaal niet nodig. Een simpele <xsl:for is voldoende :)
Ik neem aan dat je <xsl:for-each bedoelt?

Als je altijd 6 divjes wilt ongeacht de input, moet je in combinatie met de xsl:for-each wel wat boekhouding doen.
Daarnaast vind ik count(images/image)>=$i in combinatie met <xsl:if test="$i <= $count"> en de recursieve aanroep nogal omslachtig ;)
Dit is anders wel een veelgebruikte in xslt en maakt bovengenoemde boekhouding overbodig.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dank Foliant, het werkt helemaal. Ik snap alleen niet helemaal waarom ie dat als een conditie ziet. Als ik gewoon een cijfer invul (bijv. 2) dan werkt het wel gewoon. Maar goed, ik ben ook niet heel erg ervaren met XSL.

@RedRose: Ik ben benieuwd hoe je dat wil doen met een xsl for-each. Als er een makkelijkere manier is hoor ik het graag!

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Verwijderd schreef op vrijdag 13 november 2009 @ 20:29:
@RedRose: Ik ben benieuwd hoe je dat wil doen met een xsl for-each. Als er een makkelijkere manier is hoor ik het graag!
Zolang je geen 'lege nodes' wil, welke zelfs werken bij minder xml-tags in de input dan de hoeveelheid gewenste lege nodes, kan dat gewoon. In principe zijn die lege nodes ook een beetje gek in een resultaat.

Overigens gok ik dat je op 'xslt for loop' hebt gegoogeld en dit vond. Volgens mij is dit iets leesbaarder, beter, en 4 regels minder:
XML:
20
21
            <xsl:with-param name="i" select="$i + 1"/>
            <xsl:with-param name="count" select="$count"/>

Op deze manier wordt i doorgegeven als nummer, zoals het hoort, en heb je die position() dus ook niet nodig. :)
Eventueel kun je het ook nog een stuk korter maken door die 6 te 'hardcoden'.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
pedorus schreef op vrijdag 13 november 2009 @ 22:30:
[...]
Eventueel kun je het ook nog een stuk korter maken door die 6 te 'hardcoden'.
Wat stom dat ik daar niet aan gedacht heb! 6 Is helemaal niet zo veel en die kan ik er natuurlijk veel beter hard in zetten :S.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Verwijderd schreef op zaterdag 14 november 2009 @ 20:33:
[...]


Wat stom dat ik daar niet aan gedacht heb! 6 Is helemaal niet zo veel en die kan ik er natuurlijk veel beter hard in zetten :S.
Ehh, ik bedoelde dat je count niet steeds hoeft door te geven. :) Als je 6 keer 5 regels uitschrijft wordt het zelfs langer, maar bovenal wordt het lastiger aanpasbaar. Of, compleet uitgeschreven, bedoelde ik dus:
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<xsl:template match="product">
    <xsl:call-template name="show.product">
        <xsl:with-param name="i" select="1"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="show.product">
    <xsl:param name="i"/>
    
    <div id="thumb">
        <xsl:if test="count(images/image)>=$i">
            <b><xsl:value-of select="$i" /></b><img src="{images/image[$i]}" />
        </xsl:if>
    </div>

    <xsl:if test="$i &lt;= 6">
        <xsl:call-template name="show.product">
            <xsl:with-param name="i" select="$i + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

Maar het mooiste is natuurlijk als je die lege thumb-divjes gewoon weglaat en for-each gebruikt. Zie het verschil:
XML:
1
2
3
4
5
6
7
<xsl:template match="product">
    <xsl:for-each select="(images/image)[position()&lt;=6]">
        <div id="thumb">
            <b><xsl:value-of select="position()"/></b><img src="{.}"/>
        </div>
    </xsl:for-each>
</xsl:template>

En dan kun je je weer afvragen of <b>nummer</b> echt nodig is, of dat dat beter als CSS-lijst kan.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
pedorus schreef op zaterdag 14 november 2009 @ 21:10:
[...]

Maar het mooiste is natuurlijk als je die lege thumb-divjes gewoon weglaat en for-each gebruikt. Zie het verschil:
XML:
1
2
3
4
5
6
7
<xsl:template match="product">
    <xsl:for-each select="(images/image)[position()&lt;=6]">
        <div id="thumb">
            <b><xsl:value-of select="position()"/></b><img src="{.}"/>
        </div>
    </xsl:for-each>
</xsl:template>
Maar wat nou als je minder dan 6 items in je xml hebt. Dan gaat het toch niet goed? Of mis ik iets?
En dan kun je je weer afvragen of <b>nummer</b> echt nodig is, of dat dat beter als CSS-lijst kan.
Klopt, helemaal mee eens. Het was puur bedoeld als voorbeeld.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Verwijderd schreef op maandag 16 november 2009 @ 21:06:
[...]

Maar wat nou als je minder dan 6 items in je xml hebt. Dan gaat het toch niet goed? Of mis ik iets?
Je krijgt dan geen lege divjes op het einde, maar wel gewoon alle (=minder dan 6) resultaten. Dat lijkt mij persoonlijk gewoon goed. ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten

Pagina: 1