Toon posts:

[XSLT] Waarden in een Array zetten

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo allemaal,

Ik ben momenteel bezig met een webshop in xml. Het xml-bestand wordt getransformeert HTML. Maar ik kom niet helemaal uit het xsl gedeelte:
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="html" indent="yes" encoding="utf-8"/>

    <!-- Het WebshopCategorie gedeelte -->
    <xsl:template match="WebshopCategorie">
    <HTML>
    <HEAD>
        <TITLE>
            <xsl:value-of select="Titel"/>
        </TITLE>
        <LINK REL="stylesheet" TYPE="text/css" HREF="../../style.css"/>
    </HEAD>
    <BODY>
        <DIV CLASS="Titel" ALIGN="center">
            <xsl:value-of select="Titel"/>
        </DIV>
        <IMG WIDTH="175" HEIGHT="145" ALIGN="top" HSPACE="3" VSPACE="3"> 
            <xsl:attribute name="src">
                <xsl:value-of select="Foto"/>
            </xsl:attribute>
        </IMG>
        
        <xsl:copy-of select="Tekst"/>
        
        <TABLE CELLSPACING="1" CELLPADDING="0" CLASS="Tabel">
            <TR>
                <TH>Titel:</TH>
                    <xsl:for-each select="Opties/LijstVelden">
                        <TH>
                            <xsl:value-of select="LijstVeld"/>
                        </TH>
                    </xsl:for-each>
                <TH>Datum</TH>
            </TR>
            <xsl:for-each select="Producten/Product">
                <TR>
                    <TD>
                        <xsl:value-of select="Titel"/>
                    </TD>
                    <!-- Hier loop ik vast -->
                    
                    <TD>
                        <xsl:value-of select="Datum"/>
                    </TD>
                </TR>           
            </xsl:for-each>
        </TABLE>
    </BODY>
    </HTML> 
    </xsl:template>
</xsl:stylesheet>

Er zijn altijd 2 kollomen namelijk Titel en datum. Daarnaast kunnen er ook een aantal extra kolomen komen. Dit wordt bepaald door de gegevens in het element opties/LijstVelden/LijstVeld. de waarden hierin staan in relatie met de element in het "Extra" element in een Product element. Ik zat er zelf aan te denken op alle extra LijstVelden in een array te zetten maar ik denk niet dat die bestaan in XSL. (Ik heb ze nog niet gevonden iig) Voor de duidelijkheid zal ik ook mijn XML-bestand posten:
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
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="ISO-8859-1"?>
<WebshopCategorie Id="2">
  <Opties>
    <LijstVelden>
    <LijstVeld>Merk</LijstVeld>
    </LijstVelden>
  </Opties>
  <Titel>Stadsherenfietsen</Titel>
  <Foto>images/stadsherenfietsen.jpg</Foto>
  <Tekst>Stads heren fietsen</Tekst>
  <Producten>
    <Product Id="6">
    <Titel>Fiets 1</Titel>
     <Foto>fototje.jpg</Foto>
     <Tekst>De tekst</Tekst>
     <Datum>27-02-2002</Datum>
     <Extra>
       <Framehoogte>1.20</Framehoogte>
       <Kleur>Geel</Kleur>
       <Merk>Batavus</Merk>
       <Versnellingen>7</Versnellingen>
     </Extra>
    </Product>
    <Product Id="7">
     <Titel>Tweede Fiets</Titel>
     <Foto>foto.jpg</Foto>
     <Tekst>Nog wat extra commentaar op de fiets</Tekst>
     <Datum>28-02-2002</Datum>
     <Extra>
       <Framehoogte>1.10</Framehoogte>
       <Kleur>Zwart</Kleur>
       <Merk>Gazelle</Merk>
       <Versnellingen>5</Versnellingen>
     </Extra>
    </Product>
  </Producten>
</WebshopCategorie>

Iemand enig idee hoe ik dit moet oplossen?

Al vast bedank - Henk Erik

Verwijderd

Arrays zullen idd niet gaan lukken, maar kan je niet iets met standaard XPath expressies?
Als je ipv die lelijk for-each loopjes mooie templates gebruikt, kan je ook zoiets doen van
code:
1
2
3
<xsl:template match="Producten/Product/*">
  <td><xsl:value-of select="."></td>
</xsl:template>

of zoiets :?

Ik doe het uit m'n blote hoofd, dus ik kan het fout hebben :)

Verwijderd

Topicstarter
Op zondag 31 maart 2002 14:38 schreef KoenM het volgende:
Arrays zullen idd niet gaan lukken, maar kan je niet iets met standaard XPath expressies?
Als je ipv die lelijk for-each loopjes mooie templates gebruikt, kan je ook zoiets doen van
code:
1
2
3
<xsl:template match="Producten/Product/*">
  <td><xsl:value-of select="."></td>
</xsl:template>

of zoiets :?

Ik doe het uit m'n blote hoofd, dus ik kan het fout hebben :)
Maar hier los ik mijn probleem niet mee op. Ik zal het proberen (duidelijker) uit te leggen. Houd er rekening mee dat ik in dit voorbeeld uit ga van een Fietsenwinkel, maar het systeem moet gelden voor alle soorten webshops.

1) Ik heb een xml bestand met producten de structuur van een product ziet er zo uit
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Producten>
  <Product Id="n">
    <!-- Titel, Foto, Datum en Tekst bestaan altijd -->
    <Titel>Een titel</Titel
    <Foto>url naar foto</Foto>
    <Datum>**-**-****</Datum>
    <Tekst>Wat commentaar</Tekst>
    <Extra>
     <!-- Deze element kunnen veranderen -->
     <Merk>Het Merk</Merk>
     <Kleur>De Kleur</Kleur>
     <FrameHoogte>*.**</Framehoogte>
     ...
    </Extra>
  </Product>
  ...
</Producten>

2) Nu moet er op de site een lijst getoond worden van alle producten. Easy zal je denken maar ik wil graag in deze lijst ook een Element(en) uit de "Extra"-Element hebben (Laaten we zeggen "Merk"). Dit wilde ik oplossen door boven aan in het xml-bestand het volgende te zetten:
code:
1
2
3
4
5
6
7
<Opties>
  <LijstVelden>
     <!-- Hier kunnen extra "lijstvelden" worden gedefineerd -->
     <LijstVeld>Merk</LijstVeld>
     ...
  </LijstVelden>
</Opties>

In mijn bovenstaande xsl-bestand wordt de header van de lijst wel goed gemaak. Maar ik weet niet hoe ik ook een extra element kan gebruiken in de lijst.

Al vast bedankt

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Misschien dat het lukt als je gaat prutsen met child::*[name()=...] expressies, maar dat wordt erg complex.

Verwijderd

Topicstarter
Op zondag 31 maart 2002 15:23 schreef marcusk het volgende:
Misschien dat het lukt als je gaat prutsen met child::*[name()=...] expressies, maar dat wordt erg complex.
Zou je hier een voorbeeldje van kunnen geven hoe ik dit kan toepassen in mijn .xsl-bestand want ik ben nog vrij nieuw met XSLT.

Al vast bedankt

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Op zondag 31 maart 2002 16:00 schreef henkerik het volgende:
Zou je hier een voorbeeldje van kunnen geven hoe ik dit kan toepassen in mijn .xsl-bestand want ik ben nog vrij nieuw met XSLT.
Mja... het principe is dat je op die manier een node met een 'gecalculeerde' naam kunt selecteren, bv. zoiets:
code:
1
2
<xsl:variable name="field">Merk</xsl:variable>
<xsl:value-of select="Extra/child::*[name()=$field]"/>

Dan moet je alleen nog zorgen dat je de goede waarden in de variabele krijgt.

Ik weet niet of je deze al kent, maar das een erg goede XSLT Reference, waar je hierover meer info kunt vinden.

  • MisterData
  • Registratie: September 2001
  • Laatst online: 07-09 20:23
Opmerking over je manier van coden : Het is slimmer (en leesbaarder) om ipv <xsl:for-each> gebruik te maken van <xsl:template>. Als je niet weet hoe dit werkt lees dan op www.xfront.com hoe het wel moet :) Het komt de leesbaarheid alleen maar ten goede :7

Verwijderd

Topicstarter
Bedankt voor het commentaar Ik het het een en het ander eens uit proberen en ook zeker bedankt voor de Reference. Als ik er toch niet komt, kom ik wel terug

Thanx, Henk Erik

Verwijderd

Topicstarter
Ik ben even bezig geweest maar ik loop tegen een probleempje aan. De regel gaat fout:

<xsl:value-of select="/WebshopCategorie/Producten/Product/Extra/child::*[name()=$veld]"/>

Hier wordt namelijk altijd het eerste Product gekozen. Nu heb ik een variabele $id die de waarde van het Id attribute van de desbetreffende Product-node bevat. Nu eens mijn vraag hoe moet ik de bovenstaande regel aanpassen om er voor te zorgen dat steeds de juiste Product-node pakt i.p.v steeds de eerste?

De rest van de code:
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    <!-- Het WebshopCategorie gedeelte -->
    <xsl:template match="WebshopCategorie">
    <HTML>
    <HEAD>
        <TITLE>
            <xsl:value-of select="Titel"/>
        </TITLE>
        <LINK REL="stylesheet" TYPE="text/css" HREF="../../style.css"/>
    </HEAD>
    <BODY>
        <DIV CLASS="Titel" ALIGN="center">
            <xsl:value-of select="Titel"/>
        </DIV>
        <IMG WIDTH="175" HEIGHT="145" ALIGN="top" HSPACE="3" VSPACE="3"> 
            <xsl:attribute name="src">
                <xsl:value-of select="Foto"/>
            </xsl:attribute>
        </IMG>
        
        <xsl:copy-of select="Tekst"/>
        
        <TABLE CELLSPACING="1" CELLPADDING="0" CLASS="Tabel">
            <TR>
                <TH>Naam</TH>
                    <xsl:for-each select="Opties/LijstVelden/LijstVeld">
                        <TH>
                            <xsl:value-of select="."/>
                        </TH>
                    </xsl:for-each>
                <TH>Datum</TH>
            </TR>
            <xsl:for-each select="Producten/Product">
                <TR>
                    <TD>
                        <xsl:value-of select="Titel"/>
                    </TD>
                    <xsl:variable name="id">
                        <xsl:value-of select="@Id"/>
                    </xsl:variable>
                    <xsl:for-each select="/WebshopCategorie/Opties/LijstVelden/LijstVeld">
                        <xsl:variable name="veld">
                            <xsl:value-of select="."/>
                        </xsl:variable>
                        <TD>
                            <xsl:value-of select="/WebshopCategorie/Producten/Product/Extra/child::*[name()=$veld]"/>
                        </TD>
                    </xsl:for-each>                 
                    <TD>
                        <xsl:value-of select="Datum"/>
                    </TD>
                </TR>           
            </xsl:for-each>
        </TABLE>
    </BODY>
    </HTML> 
    </xsl:template>

(Over de for-each-lussen in plaats van een template-apply, 1) Wat is er mis met een for-each lus en 2) In for-each lussen heb ik geen last van de variabele scoop.)

Verwijderd

Op zondag 31 maart 2002 20:16 schreef henkerik het volgende:
1) Wat is er mis met een for-each lus
Het is IMHO minder duidelijk. Dit is een iets meer imperatieve methode: je zegt hóe je het wilt doen, en de template methode is iets meer functioneel: je zegt wát je wilt (en dus niet hoe).
Verder heb je een iets betere scheiding tussen content en XSL tags...

Verwijderd

Topicstarter
Oke thanx, Maar heeft iemand ook nog on oplossing voor mijn probleem. (zie een post hoger)?

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Dit werkt:
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" indent="yes" encoding="utf-8"/>

    <!-- Het WebshopCategorie gedeelte -->
    <xsl:template match="/WebshopCategorie">
        <xsl:variable name="velden" select="Opties/LijstVelden"/>
        
        <HTML>
        <HEAD>
            <TITLE>
                <xsl:value-of select="Titel"/>
            </TITLE>
            <LINK REL="stylesheet" TYPE="text/css" HREF="../../style.css"/>
        </HEAD>
        <BODY>
            <DIV CLASS="Titel" ALIGN="center">
                <xsl:value-of select="Titel"/>
            </DIV>
            [img]"{Foto}"[/img] 
        
            <xsl:copy-of select="Tekst"/>
        
            <TABLE CELLSPACING="1" CELLPADDING="0" CLASS="Tabel">
                <TR>
                    <TH>Titel:</TH>
                    <xsl:for-each select="$velden/child::*">
                        <TH><xsl:value-of select="."/></TH>
                    </xsl:for-each>
                    <TH>Datum</TH>
                </TR>
                <xsl:apply-templates select="Producten/Product">
                    <xsl:with-param name="velden" select="$velden"/>
                </xsl:apply-templates>
            </TABLE>
        </BODY>
        </HTML> 
    </xsl:template>
    
    <xsl:template match="Product">
        <xsl:param name="velden"/>
        <xsl:variable name="product" select="."/>
    
        <TR>
            <TD>
                <xsl:value-of select="Titel"/>
            </TD>
            <xsl:for-each select="$velden/child::*">
                <xsl:variable name="veld" select="."/>
                <TD><xsl:value-of select="$product/Extra/child::*[name()=$veld]"/></TD>
            </xsl:for-each>
            <TD>
                <xsl:value-of select="Datum"/>
            </TD>
        </TR>           
    </xsl:template>

</xsl:stylesheet>

Verwijderd

Topicstarter
Heel erg bedankt. Alles werkt perfect nu.

Thanx, Henk Erik

Verwijderd

Nog een dingetje:
Je zet in je XML welke velden je wilt zien, dus je mixed content en data. De bedoeling van XML is juist om daar een strikte scheiding tussen te maken. Je zou dus mooier in een aparte XML file de opties kunnen zetten... Maar da's een detail :).

Verwijderd

Topicstarter
Op maandag 01 april 2002 09:40 schreef KoenM het volgende:
dus je mixed content en data.
Komt dat niet op het zelfde neer? (content, data aan de ene kant tegen layout, presentatie aan de andere kant?), Maar ik begrijp wat je bedoelt, Helaas lukt het me nog steeds niet om bestanden te includen (met document functie voor xml en include voor xsl). Ik probeer in eerste instantie maar dit probleem te omzijlen tot aan het me wel lukt.
Gelukkig zijn het maar weinig instellingen dus ik hoef het niet te laten van wege de schijfruimte.
Pagina: 1