[xslt] Omzetten naar tabel*

Pagina: 1
Acties:

  • BulMi
  • Registratie: April 2006
  • Laatst online: 21-02 17:34
ik heb het volgende xml document:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<GeneralSkills>
  <GeneralSkill>
    <GeneralSkillName>Projectmanagement</GeneralSkillName>
  </GeneralSkill>
  <GeneralSkill>
    <GeneralSkillName>Coaching</GeneralSkillName>
  </GeneralSkill>
  <GeneralSkill>
    <GeneralSkillName>Training</GeneralSkillName>
  </GeneralSkill>
  <GeneralSkill>
    <GeneralSkillName>Advies</GeneralSkillName>
  </GeneralSkill>
</GeneralSkills>



Hiervan zou ik graag een tabel willen maken, met een enkele kolom lukt het, maar met 2 of 3 kolommen kom er ik niet uit.

Ik zou dus als resultaat graag willen:
code:
1
2
3
4
5
6
7
8
9
10
<table>
<tr> 
<td>Projectmanagement</td>
<td>Coaching</td>
</tr>
<tr> 
<td>Training</td>
<td>Advies</td>
</tr>
</table>l


of

code:
1
2
3
4
5
6
7
8
9
10
11
12
<table>
<tr> 
<td>Projectmanagement</td>
<td>Coaching</td>
<td>Advies</td>
</tr>
<tr> 
<td>Training</td>
<td></td>
<td></td>
</tr>
</table>l

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 20-02 15:44
Wat lukt er precies niet? Je huidige code is wel erg interessant nu!

  • BulMi
  • Registratie: April 2006
  • Laatst online: 21-02 17:34
Dit is die met 1 kolom

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
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/02/xpath-functions" xmlns:xdt="http://www.w3.org/2005/02/xpath-datatypes">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:template match="GeneralSkills">
        <table>
            <xsl:apply-templates/>
        </table>
    </xsl:template>
    
    <xsl:template match="GeneralSkill">
    <tr>
    <xsl:apply-templates/>  
    </tr>
    </xsl:template>

    <xsl:template match="GeneralSkillName">
    <td>
    <xsl:value-of select="." />
    </td>
    </xsl:template>

<xsl:template match="node()">
</xsl:template>
</xsl:stylesheet>


Maar met meerdere kolommen zit ik even helemaal vast in welke richting ik moet kijken.
Had eerst met position() mod 2 en als resultaat 0 is zet ik <tr> opening en bij 1 zet ik </tr> sluiting, maar dat mocht niet omdat het dan geen correct xml is.

Daarnaast zit ik nu te kijken naar call-template en parameters

[ Voor 36% gewijzigd door BulMi op 16-05-2006 15:09 ]


  • Sendy
  • Registratie: September 2001
  • Niet online
Lijkt me dat die position() mod 2 best wel kan werken. Waar je alleen op moet letten is dat je in het algemene geval een <tr> én een </tr> tegelijk zet. Alleen voor de eerste en de laatste moet dat niet.

  • BulMi
  • Registratie: April 2006
  • Laatst online: 21-02 17:34
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<xsl:template match="GeneralSkill">
<xsl:choose>
  <xsl:when test="position() mod 2 &gt; 0">
    <tr>
    <td>
      <xsl:value-of select="GeneralSkillName"/>
    </td>
  </xsl:when>
  <xsl:when test="position() mod 2 = 0">
    <td>
      <xsl:value-of select="dd:GeneralSkillName"/>
    </td>
    </tr>
  </xsl:when>
</xsl:choose>   
</xsl:template>


Dit was mijn eerste poging, maar hier krijg ik de fout dat de eerste <tr> geen afsluitingstag heeft.
Geprobeerd met <xsl:text> & lt; tr & gt; </xsl:text> en <![CDATA[<tr>]]> Maar dan is de output & lt; tr & gt; en geen <tr>

  • BulMi
  • Registratie: April 2006
  • Laatst online: 21-02 17:34
ik moet het nog uitproberen, maar lijk een werkende oplossing gevonden te hebben.
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
<xsl:template match="/"> 
  <html> 
    <body> 
      <table border="1"> 
        <xsl:for-each select="customers/order[position() mod 2 = 1]"> 
          <tr> 
            <td> 
              <xsl:value-of select="number"/> 
            </td> 
            <td> 
              <xsl:value-of select="description"/> 
            </td> 
            <!-- do the next <data> aswell --> 
            <td> 
              <xsl:value-of select="following-sibling::order/number"/> 
            </td> 
            <td> 
              <xsl:value-of select="following-sibling::order/description"/> 
            </td> 
          </tr> 
        </xsl:for-each> 
      </table> 
    </body> 
  </html> 
</xsl:template>

  • Dennis
  • Registratie: Februari 2001
  • Laatst online: 00:39
Hier zijn wel eerder topics over geweest op GoT, kan ik me herinneren. Onder andere Alarmnummer (geloof ik) gaf toen aan dat dit een bekende beperking is van XSLT. Er werden toen ook alternatieven aangeboden, maar ik ben niet zo thuis in die alternatieven dus dat zou je even op moeten zoeken.

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Als ik het goed begrijp wil je een lijst omzetten in een grid? Dat kan ook zo:

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<ul>
    <li>aap</li>
    <li>noot</li>
    <li>Mies</li>
    <li>Wim</li>
    <li>zus</li>
    <li>Jet</li>
    <li>Teun</li>
    <li>vuur</li>
    <li>Gijs</li>
    <li>lam</li>
    <li>kees</li>
    <li>bok</li>
    <li>weide</li>
    <li>does</li>
    <li>hok</li>
    <li>duif</li>
    <li>schapen</li>
    <li>Tweakers</li>
</ul>

XML:
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
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" > 
    
    <xsl:param name="cols" select="6" />
    
    <xsl:template match="/ul">
        <html>
            <body>
                <table border="1">
                    <xsl:apply-templates select="li[position() mod $cols = 1]"/> 
                </table>
            </body>
        </html>
    </xsl:template>
    
    <xsl:template match="li">
        <tr>
            <xsl:call-template name="col">
                <xsl:with-param name="li" select="." />
                <xsl:with-param name="pos" select="(position()-1) * $cols + 1" />
            </xsl:call-template>
        </tr>
    </xsl:template>
        
    <xsl:template name="col">
        <xsl:param name="li" />
        <xsl:param name="pos" />
        <td><xsl:value-of select="$li"/></td>
        <xsl:if test="$pos mod $cols != 0" >
            <xsl:call-template name="col">
                <xsl:with-param name="li" select="../li[position() = $pos + 1]" />
                <xsl:with-param name="pos" select="$pos + 1" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
    
</xsl:stylesheet>


Door de cols parameter van buitenaf te zetten of simpelweg bovenaan de stylesheet aan te passen kun je de breedte van het grid aanpassen. De hoogte volgt dan vanzelf.

[ Voor 56% gewijzigd door Genoil op 17-05-2006 11:44 ]


  • OnTracK
  • Registratie: Oktober 2002
  • Laatst online: 09:02
Wat Genoil doet volg ik niet helemaal, maar hij geeft nog wel een ander belangrijk punt aan: een lijst is een lijst, geen tabel!. Dus wil je ook een lijst outputten en dan (eventueel, maar hier waarschijnlijk wel) met CSS het geheel omvormen zodat de elementen naast elkaar verschijnen.

Dat kan vrij makkelijk volgens mij (als je Genoil's eerste stuk code pakt, de lijst):
Cascading Stylesheet:
1
2
3
4
5
6
7
8
9
10
11
12
ul {
    display: block;
    width: 300px;
    padding: 0px;
}

li {
    display: block;
    width: 100px;
    margin: 0px;
    float: left;
}


De enige reden waarom je de elementen naast elkaar wil laten verschijnen is visueel, dus zou je daar 0,0 mee te maken moeten hebben in je HTML output. Als je nu je xml de lijst zoals Genoil die liet zien laat outputten, en deze CSS erboven zet heb je een semantisch correcte oplossing (die óók nog eens minder moeite kost om te bouwen en minder zwaar is)

[ Voor 35% gewijzigd door OnTracK op 17-05-2006 10:18 ]

Not everybody wins, and certainly not everybody wins all the time.
But once you get into your boat, push off and tie into your shoes.
Then you have indeed won far more than those who have never tried.


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Ja wat OnTrack zegt is ook wel weer waar, maar hij begrijpt dan idd niet wat die xsl sheet doet. Die maakt van een lijst juist een tabel :). Maar het ging mij er ook niet om semantisch correcte output te genereren, ik wilde juist laten zien dat xsl uitermate geschikt is om structuren te converteren :)

  • BulMi
  • Registratie: April 2006
  • Laatst online: 21-02 17:34
Bedankt.

De oplossing van ontrack is inderdaad wat makkelijker, maar aan die van Genoil heb ik het meest :-)

Mijn voorbeeld doet vermoeden dat ik het naar html wil omzetten, maar dit was alleen om het probleem even wat makkelijker te maken. Het moet uiteindelijk wordml worden.
Echter gebruikt wordml wat meer tags om een tabel te maken dan html.

zelf had ik gisteravond de volgende oplosing:

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
<xsl:template match="dd:GeneralSkills"> 
        <table>
          <xsl:for-each select="dd:GeneralSkill[position() mod 3 = 1]"> 
          <tr> 
            <td> 
            <xsl:apply-templates select="dd:GeneralSkillName"/>
            </td> 
            <td> 
            <xsl:apply-templates select="dd:Ranking"/>
            </td> 
            <!-- do the next <data> aswell --> 
            <td> 
              <xsl:apply-templates select="following-sibling::dd:GeneralSkill[1]/dd:GeneralSkillName"/> 
            </td> 
            <td> 
              <xsl:apply-templates select="following-sibling::dd:GeneralSkill[1]/dd:Ranking"/> 
            </td> 
            <td> 
              <xsl:apply-templates select="following-sibling::dd:GeneralSkill[2]/dd:GeneralSkillName"/> 
            </td> 
            <td> 
              <xsl:apply-templates select="following-sibling::dd:GeneralSkill[2]/dd:Ranking"/> 
            </td> 
          </tr> 
        </xsl:for-each> 
      </table> 
</xsl:template> 

<xsl:template match="dd:GeneralSkillName">
<xsl:value-of select="." />
</xsl:template>

<xsl:template match="dd:Ranking">
<xsl:value-of select="." />
</xsl:template>


Maar vind die van Genoil een stuk mooier.

[ Voor 30% gewijzigd door BulMi op 17-05-2006 11:32 ]


Verwijderd

Het spijt me zeer, maar hoe weet je nu wanneer je een nieuwe kolom gaat beginnen, is dat altijd het 3e item of kan het soms ook bij het 4e item zijn?

In dat geval klopt je oplossing namelijk niet?!

Hoort er in je XML geen aanduiding te zijn over wat een skillgroep is of iets in die richting?


Aha, net alles nog maar een keer gelezen en ik snap nu geloof ik hoe je het hebben wil.

Suc6 met WordML, wat een bagger is dat. Heb hier hele producten draaien die van XML naar WordML gaan en weer terug zodat auteurs alles makkelijk aan kunnen passen.

[ Voor 32% gewijzigd door Verwijderd op 17-05-2006 11:45 ]


  • BulMi
  • Registratie: April 2006
  • Laatst online: 21-02 17:34
Hoeveel kolommen het moeten worden staat niet altijd vast, de xslt zelf wordt ook gegenereerd en in die input staat hoeveel kolommen er moeten komen. Maar dat is data onafhankelijk.
Dit stukje was ook maar 1 klein deel van het datadocument, er zijn nog 5-6 stukken die omgezet moeten worden naar tabellen en overal kan het aantal kolommen verschillen.

Maar het genereren van de xslt aan de hand van bepaalde input is het volgende probleem waar ik me mee bezig ga houden, de eerste stap was om uit te zoeken welke xslt werkt om een tabel te krijgen met meerdere kolommen
Pagina: 1