[XSL] elementen middels loop van attribuut voorzien

Pagina: 1
Acties:

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Sorry voor de titel. Hier een voorbeeld van een enkel input-veldje:
code:
1
2
3
4
5
6
7
8
9
10
11
<label for="veldnaam">Veldnaam:
    <xsl:if test="/rootelement/required/veldnaam">*</xsl:if>
    <input type="text" name="veldnaam" id="veldnaam">
        <xsl:attribute name="value">
            <xsl:value-of select="/rootelement/data/customer/veldnaam"/>
        </xsl:attribute>
        <xsl:if test="/rootelement/errors/veldnaam">
            <xsl:attribute name="class">error</xsl:attribute>
        </xsl:if>                        
    </input>
</label>


Met 20 input velden wordt het nogal veel/omslachtig. Ik kan nog steeds op 1 centrale plek bepalen welke velden verplicht zijn en ook de velden met een fout erin komen goed in het XML bestand terecht wat hier omgezet wordt in HTML. Dus de uitvoer is goed.

Maar mijn vraag is: is het mogelijk om /rootelement/errors/ door te lopen en elke <input type="text"> die een attribuut name="[value]" heeft (waarbij [value] in /rootelement/errors/ stond) een attribuut class="error" mee te geven?

Dan kan ik mijn XSL weer wat normaler opbouwen. Dat is nog lang niet perfect, maar ik wil graag weten of dat mogelijk is. Kan het niet echt vinden namelijk :)

Verwijderd

Ik denk dat het 'pipeline' pattern hier het beste geschikt voor is. Je hebt dan verschillende fases waarin je je dataset doorloopt. In elke fase voeg je dan iets specifieks toe aan het resultaat van de vorige fase.

http://www.dpawson.co.uk/xsl/sect1/N169.html#d696e386

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09-2025

djc

X-Lars schreef op donderdag 12 mei 2005 @ 17:04:
Met 20 input velden wordt het nogal veel/omslachtig. Ik kan nog steeds op 1 centrale plek bepalen welke velden verplicht zijn en ook de velden met een fout erin komen goed in het XML bestand terecht wat hier omgezet wordt in HTML. Dus de uitvoer is goed.
Waarom heb je niet 1 template voor en veld, waarin je ook de veldnaam uit de input tree haalt? Vind dit een beetje een rare aanpak.

Rustacean


  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Blues: dat ziet er wel vrij lastig uit, ik wil het vooral graag met alleen XSL doen :)

Manuzhai: bedoel je dat in de XML alle veldnamen staan, maar ook de input types? Want ik heb natuurlijk niet alleen maar <input type="text">-velden onder elkaar staan. Heb je misschien een voorbeeld van een aanpak?

Edit: Voor de duidelijkheid, hier een voorbeeld van een (ingekort) XML-bestand:
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0"?>
<rootelement>
  <data type="customer">
    <customer>
      <customer_id>1</customer_id>
      <surname>Jansen</surname>
      <city>Amsterdam</city>
      <email></email>
    </customer>
  </data>
  <required>
    <customer_id/>
    <surname/>
    <email/>
  </required>
  <errors>
    <email/>
  </errors>
</rootelement>
Het required-element wordt meestal toegevoegd, het error-element alleen na een POSTed form. Aan de hand van dit enkele XML document wil ik dus mijn HTML opbouwen.

[ Voor 67% gewijzigd door X-Lars op 13-05-2005 08:19 ]


Verwijderd

X-Lars schreef op vrijdag 13 mei 2005 @ 08:14:
Blues: dat ziet er wel vrij lastig uit, ik wil het vooral graag met alleen XSL doen :)
Pipelining kan ook met alleen XSL. Wat je doet is het volgende:
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
<!--
  creeer je basic formulier met alle inputs, adhv je data-types
-->
<xsl:variable name="create-inputs">
  <xsl:apply-templates select="/" mode="phase-1"/>
</xsl:variable>


<!--
  neem het gecreeerde formulier en voeg de eigenschappen van
  requiredness (het *, etc) aan toe
-->
<xsl:variable name="add-requiredness">
  <xsl:apply-templates select="$create-inputs" mode="add-requiredness"/>
</xsl:variable>


<!--
  voeg dan vervolgens de eigenschappen van errors (class="error") toe
-->
<xsl:variable name="add-errors">
  <xsl:apply-templates select="$add-requiredness" mode="add-errors"/>
</xsl:variable>


<!--
  gebruik het uiteindelijke formulier als output
-->
<xsl:template match="/">
  <xsl:copy-of select="$add-errors"/>
</xsl:template>


Hoe de templates eruit moeten zien kun je waarschijnlijk zelf wel bedenken ;)

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Tnx Blues! Dat ziet er heel veelbelovend uit. Maar ik weet er nog te weinig van om dat 1-2-3 te implementeren. Dus ben ik eerst even wat gaan proberen:
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
<xsl:template match="/">
    <html>
        <head>
            <title>XSLT Test</title>
        </head>
        <body>
            <input type="text"></input>
        </body>
    </html>
</xsl:template>

<xsl:variable name="add-input-name">
    <xsl:apply-templates select="/" mode="phase-1"/>
</xsl:variable>

<xsl:template name="add-input-name">
    <for-each select="input">
        <xsl:copy use-attribute-sets="input"/>
    </for-each>
<xls:template>
    
<xsl:attribute-set name="input">
     <xsl:attribute name="name">test</xsl:attribute>
</xsl:attribute-set> 

<xsl:variable name="finish">
    <xsl:copy-of select="$add-input-name"/>
</xsl:variable>

<xsl:template match="/">
    <xsl:copy-of select="$finish"/>
</xsl:template>
Het enige wat ik hier wil is dat aan het input-veld een attribuut "name" met waarde "test" wordt toegevoegd. Maar dat wil dus al niet echt :p

Maakt de volgorde van die xsl-stukjes iets uit trouwens?

[ Voor 21% gewijzigd door X-Lars op 18-05-2005 16:58 ]


  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Goed, nog een test gedaan:
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
<xsl:template match="/" mode="phase-1">
    <html>
        <head>
            <title>XSLT Test</title>
        </head>
        <body>
            <input type="text"></input>
        </body>
    </html>
</xsl:template>

<xsl:variable name="phase1">
    <xsl:apply-templates select="/" mode="phase-1"/>
</xsl:variable>

<xsl:template match="/" mode="phase-2">
    <xsl:copy-of select="$phase1"/>
</xsl:template>

<xsl:variable name="phase2">
    <xsl:apply-templates select="/" mode="phase-2"/>
</xsl:variable>

<xsl:template match="/">
    <xsl:copy-of select="$phase2"/>
</xsl:template>
Dit slaat op zich nergens op natuurlijk, hij kopieert gewoon de template 2x. Maar dan snap ik dat in ieder geval. Maar hoe kan ik hier nou een template op los laten i.p.v. domweg kopieren? Heb zojuist al vanalles geprobeerd, maar het lukt maar niet.

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Topicstarter
Nu kom ik er ook achter dat er op "tijdelijke bomen" pas in XSLT 2.0 xsl:apply-templates kan worden toegepast: http://www.diderottrack.nl/nl.articles.xslt1and2.html

Maar blijkbaar ondersteunt de XSL extension in PHP5 dat dan weer niet, want dit geeft een "Warning: xsl:version: only 1.0 features are supported...":
PHP:
1
2
$objXSLProc = new xsltProcessor;
$objXSLProc->importStyleSheet(DomDocument::load('test.xsl'));
Pagina: 1