Toon posts:

[xsl/xslt] tabel voorzien van header

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben relatief nieuw op .xml / .xslt gebied, en loop nu tegen een probleem aan waarvoor ik de oplossing niet echt kan vinden.


Stel ik heb de volgende .xml (stukje)

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
  <samenstelling>
    <samenstelling_naam>s1</samenstelling_naam>
    <item>
      <item_naam>item 1</item_naam>
      <item_onderdelen>
        <item_onderdeel>
          <item_onderdeel_naam>onderdeel 1</item_onderdeel_naam>
          <item_subonderdelen>
            <item_subonderdeel>
              <item_subonderdeel_naam>subonderdeel 1<item_subonderdeel_naam>
              <waarde_1>w1</subonderdeel_prop1>
              <waarde_2>w2</subonderdeel_prop2>      
            </item_subonderdeel>
            <item_subonderdeel>
              <item_subonderdeel_naam>subonderdeel 2<item_subonderdeel_naam>
              <waarde_1>w3</subonderdeel_prop1>
              <waarde_2>w4</subonderdeel_prop2>
            </item_subonderdeel>
          <item_subonderdelen>          
        </item_onderdeel>
      </item_onderdelen>
    </item>   
  </samenstelling>
  <samenstelling>
     <samenstelling_naam>s2</samenstelling_naam>
... enzovoort     


Oftewel elke samenstelling bestaat uit items, welke bestaan uit onderdelen welke bestaan uit subonderdelen, waarbij er aan die subonderdelen nog properties hangen. Ik weet niet hoeveel onderdelen of subonderdelen er zullen zijn, maar wel dat dit voor alle samenstellingen binnen het xml bestand dezelfde items/onderdelen/subonderdelen gelden.
Bijvoorbeeld de naam van alle onderdelen voor elk item binnen één xml is dus gelijk, en wil ik als kolomtitel gebruiken.

Nu wil ik dit bestand dmv. een .xls in een tabel presenteren, zodanig dat er boven de kolommen de titels staan, waarbij 'overkoepelende titels' gebruik maken van een rowspan.

Dat wil zeggen, de 1e regel uit de tabel bevat alleen de itemnamen, met een colwidth zodanig dat deze duidelijk voor alleen dat item geldt.

De 2e regel uit de tabel bevat alleen de onderdeelnamen, met een colwidth zodanig dat deze duidelijk voor dat onderdeel geldt

De 3e regel uit de tabel bevat alleen de subonderdeelnamen, met een colwidth zodanig dat deze duidelijk voor dat subonderdeel geldt

De 4e regel bevat de 'subonderdeel-waarde-namen' met colwidth=1.

en pas daarna komen de eigenlijke gegevens.

Je krijgt dan dus zo'n soort tabel:
code:
1
2
3
4
5
6
7
8
9
10
11
+-----------------+-----------------------------------------+
| samenstelling   |item                                     |
|                 +-----------------------------------------+
|                 |onderdeelnaam 1                          |
|                 +--------------------+--------------------+
|                 |subonderdeel 1      |subonderdeel 2      |
|                 +---------+----------+---------+----------+
|                 |waarde 1 | waarde 2 |waarde 1 | waarde 2 |
+-----------------+---------+----------+---------+----------+
|  s1             | w1      |  w2      |  w3     |   w4     |
|  s2             | ......... enzovoort


Nu heb ik echt geen flauw idee waar te beginnen. M'n gegevens krijg ik wel in die kolommen, dat is het probleem niet. Maar hoe krijg ik de juiste titels boven de kolommen? Die titels zitten immers in de gegevens zelf..

Ik kan de hele set gewoon 2 keer doorlopen, en dan de 1e keer alleen de 'tabel-header' aanmaken en de 2e keer alleen de tabelinhoud, maar is er geen methode om dit in één keer te doen?

//edit
Ik hoop dat het probleem zo een beetje duidelijk omschreven is, kan er niet veel beters van maken.

Wat ik zelf gedaan heb: de xml en de xsl tutorial van W3C gevolgd, uren googlen, zoeken op GoT.. maar niets kunnen vinden wat dit probleem omschrijft.

//edit 2

ik verwacht geen panklare oplossing ofzo, zelfs niet perse voorbeeldcode.. zuiver een paar hints in welke richting ik moet gaan googlen, dan kom ik er zelf wel uit..

[ Voor 38% gewijzigd door Verwijderd op 29-06-2004 11:52 ]


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Ik kan de hele set gewoon 2 keer doorlopen, en dan de 1e keer alleen de 'tabel-header' aanmaken en de 2e keer alleen de tabelinhoud, maar is er geen methode om dit in één keer te doen?
XSLT is niet echt een kwestie van 'doorlopen', tenzij je (best wel een beetje fout) de voorkeur geeft aan <xsl:for-each />. Het gemakkelijkste is twee keer matchen in een verschillende mode:

XSLT:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<xsl:template match="/samenstellingen">
    <table> 
    <xsl:apply-templates mode="header" />
    <xsl:apply-templates mode="values" />
    </table>     
</xsl:template>

<xsl:template match="samenstelling" mode="header">
    <!-- hier je header spul -->
</xsl:template>
    
<xsl:template match="samenstelling" mode="values">
    <!-- hier je values spul -->
</xsl:template>

Verwijderd

Topicstarter
Tsja.. dat bedoelde ik met 'doorlopen'.

Ik ben hier mee aan het experimenteren, maar kom er niet uit. Waarom zet hij allemaal rotzooi ertussen waar ik niet om gevraagd heb?

Als ik bv. dit doe:

code:
1
2
3
4
5
6
7
8
9
10
11
12
<xsl:template match="/samenstellingen">
    <table> 
    <xsl:apply-templates mode="header" />
    <xsl:apply-templates mode="values" />
    </table>     
</xsl:template>

<xsl:template match="samenstelling" mode="header">
  <xsl:for-each select="samenstelling\item\item_onderdelen\item_onderdeel"
     <xsl:value-of select="item_onderdeel_naam"/>
  </xsl:for-each>
</xsl:template>


dan zou ik een lijst verwachten met alleen de onderdeelnamen erin. Die geeft hij ook weer, maar hij frot alle tussenliggende velden er stiekum toch tussen, terwijl ik die niet geselecteerd heb.

Je krijgt dan dus bv:
code:
1
  onderdeel1item1s1

als resultaat terwijl ik toch echt alleen om 'onderdeel_1' gevraagd had ?!

[ Voor 11% gewijzigd door Verwijderd op 29-06-2004 13:13 ]


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
mijn XSLT processor bakt helemaal niets van je voorbeeldcode...ik neem aan dat je in je eigen werkende code wel overal alle tags goed afsluit en werkt met / ipv \ in je selects?

als ik er dit van maak:

code:
1
2
3
4
5
    <xsl:template match="samenstelling" mode="header">
          <xsl:for-each select="item/item_onderdelen/item_onderdeel">
             <xsl:value-of select="item_onderdeel_naam"/>
          </xsl:for-each>
    </xsl:template>


dan krijg ik gewoon "onderdeel1" als output

[ Voor 47% gewijzigd door Genoil op 29-06-2004 13:29 ]


Verwijderd

Topicstarter
[knip] hier ging iets mis [/knip]

[ Voor 186% gewijzigd door Verwijderd op 29-06-2004 13:54 ]


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
ah ok typos dus...gelukkig maar :P

maar ik snapte idd de structuur al niet helemaal. je hebt meerdere samenstellingen, maar een samenstelling kan ook weer meerdere items hebben? Ik was er in m'n hoofd vanuit gegaan dat de meerdere items dan gewoon in de tabel naast elkaar komen te staan, klopt dat?

Is het overigens mogelijk om ipv waarde_1 en waarde_2 gewoon "waarde" te nemen? Da's een stukje gemakkelijker bij het bepalen van de colspans...

Verwijderd

Topicstarter
hmm.. toch werkt het niet, wat ik zei klopt wel.. als ik deze .xml neem:

XML:
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="Windows-1252"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
  <item>
      <test>blaat</test>
      <onderdelen>
        <onderdeel>
           <onderdeel_tekst>tekst</onderdeel_tekst>
        </onderdeel>
      </onderdelen>
  </item>


en deze xsl:
code:
1
2
3
4
5
6
7
8
9
10
11
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <xsl:apply-templates mode="header" />
</xsl:template>

<xsl:template match="/item/onderdelen" mode="header">
  <xsl:for-each select="onderdeel">
     <xsl:value-of select="onderdeel_tekst"/> 
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>


dan krijg ik als resultaat:
code:
1
blaattekst


terwijl ik alleen 'tekst' had verwacht?

//edit2
dit probleem is inmiddels opgelost. Ik moet dan nog een / voor de "onderdeel_tekst" zetten.

//edit het gaat weer lekker
maar ik snapte idd de structuur al niet helemaal. je hebt meerdere samenstellingen, maar een samenstelling kan ook weer meerdere items hebben? Ik was er in m'n hoofd vanuit gegaan dat de meerdere items dan gewoon in de tabel naast elkaar komen te staan, klopt dat?
Inderdaad :)
Is het overigens mogelijk om ipv waarde_1 en waarde_2 gewoon "waarde" te nemen? Da's een stukje gemakkelijker bij het bepalen van de colspans...
Helaas.. maar op dat punt zit het mee: er zijn altijd 2 waardes per subonderdeel. Maar het aantal subonderdelen per onderdeel is dus niet bekend, evenmin het aantal onderdelen per item.

Ik denk dat ik maar eens naar de boekhandel loop, want ik heb het gevoel dat ik jullie lastig val met _te_ basic vragen :P

[ Voor 60% gewijzigd door Verwijderd op 29-06-2004 14:09 ]


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
De reden dat je 'blaattekst' krijgt is omdat zowel de eerste als de tweede template matched vanaf de root.

In de eerste template doe je vervolgens een apply-templates zonder specifieke selectie, en als er niet specifiek gematched wordt op het een element , zit XSLT zo in elkaar dattie dan gewoon de inhoud van dat element kopieert.

Op de /item/onderdelen wordt wel gematched en daar wordt (geheel in lijn met jouw verwachtingen) dus gewoon 'tekst' door afgedrukt.
ik verwacht geen panklare oplossing ofzo, zelfs niet perse voorbeeldcode
echt niet? ik heb nml iets werkends :P
(echt nix te doen vandaag opt werk dus maar xslt probleempjes van gotters aan het oplossen ;))

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
hier, copy-paste maar niet als je het zlef wilt uitvinden ;)
deze werkt met een willekeurig aantal samenstellingen, items, onderdelen en subonderdelen.

XSLT:
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
59
60
61
62
63
64
65
66
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:output method="xhtml" 
                indent="yes" 
                doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 
                doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
                omit-xml-declaration="yes" />
    
    <xsl:template match="/samenstellingen">
        <table border="1"> 
            <xsl:apply-templates mode="header" />
            <xsl:apply-templates mode="values" />
        </table>     
    </xsl:template>
    
    <xsl:template match="samenstelling" mode="header">
        <tr>
            <th rowspan="4">samenstelling</th>
            <xsl:apply-templates select="item" />
        </tr>
        <tr>
            <xsl:apply-templates select="//item_onderdeel" />
        </tr>
        <tr>
            <xsl:apply-templates select="//item_subonderdeel" />
        </tr>
        <tr>
            <xsl:apply-templates select="//waarde_1|//waarde_2" mode="header" />
        </tr>
    </xsl:template>
    
    <xsl:template match="samenstelling" mode="values">
        <tr>
            <td><xsl:value-of select="samenstelling_naam" /></td>
            <xsl:apply-templates select="//waarde_1|//waarde_2" mode="values" />
        </tr>
    </xsl:template>
      
    <xsl:template match="item">  
        <th colspan="{2*count(.//item_subonderdeel)}">
            <xsl:value-of select="item_naam" />
        </th>
    </xsl:template>
    
    <xsl:template match="item_onderdeel">  
        <th colspan="{2*count(.//item_subonderdeel)}">
            <xsl:value-of select="item_onderdeel_naam" />
        </th>
    </xsl:template>
    
    <xsl:template match="item_subonderdeel">  
        <th colspan="{2*count(.)}">
            <xsl:value-of select="item_subonderdeel_naam" />
        </th>
    </xsl:template>
    
    <xsl:template match="waarde_1|waarde_2" mode="header">  
        <th><xsl:value-of select="name()" /></th>
    </xsl:template>

    <xsl:template match="waarde_1|waarde_2" mode="values">  
        <td><xsl:value-of select="." /></td>
    </xsl:template>
    
</xsl:stylesheet>

Verwijderd

Topicstarter
wow thanks, jij had echt niets te doen :P

Hier kan ik echt wat mee, tesamen met m'n nieuwe boek 'xml voor ontzettende reetkevers' :P

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Verwijderd schreef op 29 juni 2004 @ 18:40:
wow thanks, jij had echt niets te doen :P

Hier kan ik echt wat mee, tesamen met m'n nieuwe boek 'xml voor ontzettende reetkevers' :P
nja het lijkt ingewikkelder dan het is, zo lang ben ik er niet mee bezig geweest ;)

als 'xml voor ontzettende reetkevers' toch een beetje te eenvoudig voor je is, zou ik eens kijken naar het boek van XSLT-kabouter:

Afbeeldingslocatie: http://media.wiley.com/product_data/coverImage/14/07645438/0764543814.jpg

de kabouter weet alles!
Pagina: 1