XSLT - Adv. "weergeven in (bijv) 4 kolommen"

Pagina: 1
Acties:

  • vulcan
  • Registratie: April 2000
  • Laatst online: 13-08 13:43
Vergelijkbaar met een vorig draadje maar wel degelijk anders:


Stel ik heb de volgende XML:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="aanbiedingen.xsl"?>
<dataset>
<aanbiedingen>
    <aanbieding>1</aanbieding>
    <aanbieding>2</aanbieding>
    <aanbieding>3</aanbieding>
    <aanbieding>4</aanbieding>
    <aanbieding>5</aanbieding>
</aanbiedingen>
<aanbiedingen>
    <aanbieding>6</aanbieding>
    <aanbieding>7</aanbieding>
    <aanbieding>8</aanbieding>  
    <aanbieding>9</aanbieding>
</aanbiedingen>
</dataset>

en de volgende xsl(deel van):
code:
1
2
3
4
5
6
7
8
9
<xsl:template match="//aanbiedingen//aanbieding">
  <xsl:if test="(position() mod 3) = 1">
    <tr>
    <td><xsl:value-of select="./self::*" /></td>
    <td><xsl:value-of select="./following-sibling::*" /></td>
    <td><xsl:value-of select="./following-sibling::*/following-sibling::*" /></td>
    </tr>
  </xsl:if>
</xsl:template>

de output is dan als volgt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<table border="1" cellspacing="2" cellpadding="2" width="300">
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
    <td>5</td>
    <td></td>
  </tr>
  <tr>
    <td>7</td>
    <td>8</td>
    <td>9</td>
  </tr>
  <tr>
    <td>10</td>
    <td></td>
    <td></td>
  </tr>
</table>

Je ziet dat de er een nieuwe regel(<tr>) voor de 2e <aanbiedingen>-node wordt gemaakt. Dit is, voor mij althans, niet de bedoeling.

De bedoeling is dat nummer 7 gewoon achter nummer 6 komt(op de vorige rij dus)

aardig vergelijkbaar met een vorig draadje, echter daar stonden de items die moesten worden gegroepeerd in de zelfde node. Dit is bij mij niet het geval en staan op verschillende plekken binnen het xml-document. (vandaar ook de '//' voor de aanbiedingen.

iemand suggesties?

alvast bedankt!

Je kan het laten, je kan het doen of je kan het laten doen


  • Rense Klinkenberg
  • Registratie: November 2000
  • Laatst online: 09-08 19:19
mm, dit is al eens eerder geweest, helaas is ie niet meer te vinden met de search :-(

  • vulcan
  • Registratie: April 2000
  • Laatst online: 13-08 13:43
Op woensdag 10 juli 2002 17:17 schreef freak007 het volgende:
mm, dit is al eens eerder geweest, helaas is ie niet meer te vinden met de search :-(
Yep :'( kheb aardig lopen zoeken en alleen jouw probleem kunnen vinden.. maar dit is iets anders....
Ik heb overigens wel jouw voorbeeld gebruikt om het een en andere te proberen, maar tevergeefs.

Je kan het laten, je kan het doen of je kan het laten doen


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Beetje goochelen, maar een leuk resultaat ;) . De sleutel tot deze oplossing is de //aanbieding.
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
<?xml version="1.0"?>

<xsl:transform version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns="http://www.w3.org/1999/xhtml">

  <xsl:output   method="xml" indent="yes" encoding="UTF-8"
      doctype-public="-//W3C//DTD XHTML 1.1//EN"
      doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/>

  <xsl:template match="/dataset">
    <html>
    <head>
      <title>Example</title>
    </head>

    <body>
      <table>
        <tbody>
        <xsl:apply-templates select="//aanbieding"/>
        </tbody>
      </table>
    </body>
    </html>
  </xsl:template>

  <xsl:template match="text()"/>

  <xsl:template match="aanbieding[count(preceding::aanbieding) mod 3 = 0]">
    <tr>
    <td>
      <xsl:value-of select="text()" />
    </td>
    <td>
      <xsl:value-of select="following::aanbieding/text()" />
    </td>
    <td>
      <xsl:value-of select="following::aanbieding/following::aanbieding/text()" />
    </td>
    </tr>
  </xsl:template>
</xsl:transform>

Resultaat:
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
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
                "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Example</title>
  </head>
  <body>
    <table>
    <tbody>
      <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
      </tr>
      <tr>
        <td>4</td>
        <td>5</td>
        <td>6</td>
      </tr>
      <tr>
        <td>7</td>
        <td>8</td>
        <td>9</td>
      </tr>
    </tbody>
    </table>
  </body>
</html>

Ik vind hem wel yummie, ook al zeg ik het zelf :+ .

De oude topic is deze, maar dit was toch een iets ander probleem geloof ik:

[topic=289102/1/400]

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Nu ik er nog even naar kijk, zit de oplossing eigenlijk meer in de preceding axis. Soms wil je deze oplossing misschien niet als er nog andere aanbieding nodes zijn die niet weergegeven worden in de tabel. Deze tellen dan namelijk ook mee bij de preceding count.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Omdat je hier toch wel een flink aantal gebreken ziet in XSLT, is het misschien wel leuk om te laten zien wat je in een krachtige transformatie taal zou kunnen doen. Ik heb daarom een voorbeeld gemaakt in Stratego, wat imho een krachtige transformatie-taal is ;) . In dit voorbeeld specificeer ik op een hele duidelijke, functioneel-achtige, manier de transformatie van de aanbiedingen naar de tabel.

Eerst even de structuur die ik gebruik:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
dataset(
  [ aanbiedingen(
    [ aanbieding(1)
    , aanbieding(2)
    , aanbieding(3)
    , aanbieding(4)
    , aanbieding(5)
    ]
    )
  , aanbiedingen(
    [ aanbieding(6)
    , aanbieding(7)
    , aanbieding(8)
    , aanbieding(9)
    ]
    )
  ]
)

Dit ziet er misschien heel erg vreemd uit, maar dit is de ATerm tegenhanger van het XML document met de aanbiedingen. ATermen hebben een aantal verschillen tov van XML: er zijn bijvoorbeeld geen sluit-tags en ze hebben lijsten: [1,2,3].

Je ziet hier een dataset met als argument een lijstje van aanbiedingen, waarbij elke aanbiedingen weer een lijstje van aanbieding-en bevat.

Dit ziet er in een Stratego signatuur zo uit:
code:
1
2
3
4
5
6
7
8
constructors
  dataset:  List(aanbiedingen) -> dataset
  aanbiedingen: List(aanbieding)   -> aanbiedingen
  aanbieding:   int -> aanbieding

  table:      List(tr) -> table
  tr:        List(td) -> tr
  td:        String   -> td

Dit is een regular tree grammar voor het document wat jij eerder plaatste. Stratego signatures hebben een sterke overeenkomst met RELAX NG, wat een schema taal voor XML is en die ook is gebaseerd op regular tree grammars.

Dan nu de transformatie zelf:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
strategies

  main =
    iowrap(
    collect(?aanbieding(_))
    ; group
    ; map(map(to-td); to-tr); !table(<id>)
    )

  group: [x1, x2, x3 | xs] -> [[x1, x2, x3] | <group> xs]
  group: [x1, x2]       -> [[x1, x2,   None]]
  group: [x1]         -> [[x1, None, None]]
  group: []         -> []

  to-td = ?aanbieding(<id>); is-int; !td(<int-to-string>)
  to-td = ?None;  !td("-")

  to-tr = !tr(<id>)

Dit is waarschijnlijk op z'n minst hokus-pokus, maar als je ooit functioneel programmeren hebt gezien moet het wel begrijpelijk overkomen. Deze definitie is naast dat hij een stuk compacter is, ook een stuk duidelijker: je weet exact wat er gebeurd en je hebt alle mogelijkheden bij de hand om te realiseren wat je wilt bereiken (zie bijvoorbeeld de map functie en de pattern-matching in de group regels).

Wat doe ik hier?

In de collect(?aanbieding(_)) regel vis ik alle aanbieding elementen uit de input en verzamel deze in een lijst.

Het resultaat hiervan is:
code:
1
2
3
4
5
6
7
8
9
10
[ aanbieding(1)
, aanbieding(2)
, aanbieding(3)
, aanbieding(4)
, aanbieding(5)
, aanbieding(6)
, aanbieding(7)
, aanbieding(8)
, aanbieding(9)
]

Deze lijst wordt op een duidelijke manier gegroepeerd met de group regels. Als een group niet compleet is, vul ik ze op met 'None'. Merk overigens nog even op dat de group functie natuurlijk veel generiekere kan, bijvoorbeeld door zelf het aantal elementen op te geven waarin de lijst verdeeld moet worden. Dit kan je in Stratego prima uitdrukken, maar om het nog een beetje begrijpelijk te houden heb ik dit maar niet gedaan ;) .

Het resultaat hiervan is dit:
code:
1
2
3
4
[ [aanbieding(1), aanbieding(2), aanbieding(3)]
, [aanbieding(4), aanbieding(5), aanbieding(6)]
, [aanbieding(7), aanbieding(8), aanbieding(9)]
]

(helaas zie je de None in dit voorbeeld niet terug)

Op het laatst zet ik de groepering om naar een table door een paar handige map aanroepen. Het resultaat daarvan is:
code:
1
2
3
4
5
6
table(
  [ tr([td("1"),td("2"),td("3")])
  , tr([td("4"),td("5"),td("6")])
  , tr([td("7"),td("8"),td("9")])
  ]
)

Het is misschien allemaal erg ingewikkelde code om Stratego nogal een compact taaltje is, maar het zal wellicht wel duidelijk geworden zijn hoe krachtig je zo'n transformatie kunt uitdrukken als je een echt fatsoenlijke taal tot je beschikking hebt.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • vulcan
  • Registratie: April 2000
  • Laatst online: 13-08 13:43
Joh, jij zit ook niet stil he? tnx!

Bedankt voor je antwoorden(nog niet gelezen, nu aan het doen :9~)

:)

Je kan het laten, je kan het doen of je kan het laten doen


  • vulcan
  • Registratie: April 2000
  • Laatst online: 13-08 13:43
Wel balen dat ik gisteravond om 21:00 van ellende in slaap ben gevallen.. :P anders had ik NOG lekkerder geslapen.

Het werkt! :) tnx mate! B-)

Ik ga je voorbeeldjes van Stratego even doorworstelen....

Je kan het laten, je kan het doen of je kan het laten doen


  • vulcan
  • Registratie: April 2000
  • Laatst online: 13-08 13:43
mbravenboer:

waarin maak jij je XML en XSL(T) documenten? Ook in je vorige postings zie ik mooie gestructureerde documenten welke allemaal de zelfde soort opbouw hebben.

Lijkt me hetzelfde pakket? XML Spy en XSLT Designer?

ben benieuwd....

Je kan het laten, je kan het doen of je kan het laten doen


  • Dennis
  • Registratie: Februari 2001
  • Laatst online: 20:24
Met inspringen kun je al een hoop ;)

  • vulcan
  • Registratie: April 2000
  • Laatst online: 13-08 13:43
gelukkig wel ja.. :P

maar dit zag er niet notepad-achtig uit..

het kan wel natuurlijk.. maar zo'n prof als mbravenboer (>:)) werkt natuurlijk niet met notepad..... ;)

Je kan het laten, je kan het doen of je kan het laten doen


Verwijderd

Op donderdag 11 juli 2002 09:11 schreef vulcan het volgende:
mbravenboer:

waarin maak jij je XML en XSL(T) documenten? Ook in je vorige postings zie ik mooie gestructureerde documenten welke allemaal de zelfde soort opbouw hebben.

Lijkt me hetzelfde pakket? XML Spy en XSLT Designer?

ben benieuwd....
Hij werkt vooral met SuSE linux dus XML spy zal het niet zijn, ik gok op JExt :X

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
vulcan: Het werkt! :) tnx mate! B-)
Mooi :) .

Stratego transformeert op dit moment trouwens alleen nog maar ATermen, maar ik ben met tools bezig om XML input en output mogelijk te maken. Als je dit echt boeiend vindt kan je er hier een presentatie over vinden. Verder gaat Stratego binnenkort naar Java/C# compileren, waardoor je het ook op andere platformen kunt gaan gebruiken.
vulcan: waarin maak jij je XML en XSL(T) documenten? Ook in je vorige postings zie ik mooie gestructureerde documenten welke allemaal de zelfde soort opbouw hebben.
Zef: Hij werkt vooral met SuSE linux dus XML spy zal het niet zijn, ik gok op JExt :X
Goed gegokt ;) . Ik gebruik inderdaad Jext. Jext heeft geen speciale XML support, maar wel goede syntax kleuring voor XML. Ik gebruik gewoon tabs (2 spaties). Ik hecht waarde aan een duidelijke layout, dus vandaar dat het er altijd goed uitziet :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment

Pagina: 1