[XSLT] Muenchian Grouping

Pagina: 1
Acties:

  • bodiam
  • Registratie: December 2001
  • Laatst online: 31-12-2024
Beste allen,

Ik ben bezig met het transformeren van een simple XML boom (zie onder). Ik moet daarvoor groeperen op elementen die diep in de boom zitten. Om te grouperen gebruik ik geen XSLT 2.0 group-by functie, maar de Muenchian Grouping methode (zie http://www.jenitennison.com/xslt/grouping/). Echter, zoals je waarschijnlijk al kon raden, ik kom er niet uit. Mijn structuur is namelijk ietwat anders, waardoor het groeperen (en uniek maken) van de elementen niet 100% correct werkt.

Concreet is het probleem dat er wel ge-grouped-by wordt op het eerste "Group" element, maar niet op de 2de. In onderstaande XML heb ik 4 groepen (A, A, B en C), waarvan 3 unieke groepen (Groep A, B en C dus). In mijn HTML zie ik echter groep C niet, waardoor ik er achter ben gekomen dat alleen gegroepeerd wordt wordt op de 1ste instantie van het Group element, terwijl er per Sample 2 Group elementen zijn.

Heeft iemand suggesties die mij verder kunnen helpen? Alvast heel erg bedankt, dit kost me nu al 3 dagen namelijk :(

Erik


XML

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
37
38
39
40
41
42
43
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="simpleXSL.xsl"?>
<Result>
    <Act>
        <Sample>
            <Name>BL</Name>
            <Analysis>
              <Description>Description 1</Description>
              <AnalysisResult>
                <Value>1</Value>
              </AnalysisResult>
              <Group>Groep A</Group>
            </Analysis>
            <Analysis>
              <Description>Description 2</Description>
              <AnalysisResult>
                <Value>40</Value>
              </AnalysisResult>
              <Group>Groep A</Group>
            </Analysis>
        </Sample>
    </Act>
    
    <Act>
        <Sample>
            <Name>BL</Name>
            <Analysis>
              <Description>Description 3</Description>
              <AnalysisResult>
                <Value>10</Value>
              </AnalysisResult>
              <Group>Groep B</Group>
            </Analysis>
            <Analysis>
              <Description>Description 4</Description>
              <AnalysisResult>
                <Value>240</Value>
              </AnalysisResult>
              <Group>Groep C</Group>
            </Analysis>
        </Sample>
    </Act>
</Result>


XSLT

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
        <html>
            <body>
                    <xsl:apply-templates />
            </body>
        </html>
    </xsl:template>

    <xsl:key name="acts-by-group" match="Act" use="Sample/Analysis/Group" />
    <xsl:template match="Result">
        <xsl:for-each select="Act[count(. | key('acts-by-group', Sample/Analysis/Group)[1]) = 1]">
            <xsl:sort select="Sample/Analysis/Group" />
        <xsl:value-of select="Sample/Analysis/Group" />,<br />
        </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>



HTML

HTML:
1
2
3
4
<html>
  <body>Groep A,<br>Groep B,<br>
  </body>
</html>


Maar zou moeten zijn:

HTML:
1
2
3
4
<html>
  <body>Groep A,<br>Groep B,<br>Groep C,<br>
  </body>
</html>

  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
ipv grouperen kan je ook alleen Group elementen selecteren die je nog niet hebt gehad.
bijv:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:template match="/Result">
    <html>
        <body>
            <xsl:apply-templates select="Act/Sample/Analysis/Group[not(. = preceding::Group)]" />
        </body>
    </html>
    </xsl:template>
    
    <xsl:template match="Group">
        <xsl:value-of select="." />
        <xsl:text>, </xsl:text>
        <br/>
    </xsl:template>
    
</xsl:stylesheet>

[ Voor 23% gewijzigd door joopst op 09-08-2005 11:54 . Reden: roze knop ingevoegd ]


  • bodiam
  • Registratie: December 2001
  • Laatst online: 31-12-2024
Bedankt Joopst,

Maar dit is niet helemaal wat ik bedoel, of het is een onderdeel van de totale oplossing, waarbij ik de rest nog even niet kan plaatsen. Het geeft inderdaad hetzelfde effect als mijn gewenste output, maar mijn output was een (te simpele) versimpeling van de werkelijkheid. Ik wil namelijk niet dat de overige group elementen genegeerd worden, ik wil een group by doen. Het resultaat moet er dus ongeveer zo uit kunnen zien (de ingesprongen stukken zijn Value elementen):

code:
1
2
3
4
5
6
7
Groep B
+ -- 10
Groep A
+ -- 40
+ -- 1
Groep C
+ -- 240

[ Voor 85% gewijzigd door bodiam op 09-08-2005 13:01 ]


  • bodiam
  • Registratie: December 2001
  • Laatst online: 31-12-2024
Ter verduidelijking: ik ben echt op zoek naar een manier om mijn Group elementen te "Group-By"-en. Niet om ze te negeren, maar ik heb ze nodig om de overige elementen binnen mijn XML document op te grouperen.

  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
Als ik jou was zou ik er gewoon een template bij plakken dan :-)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:template match="/Result">
    <html>
        <body>
            <xsl:apply-templates select="Act/Sample/Analysis/Group[not(. = preceding::Group)]" />
        </body>
    </html>
    </xsl:template>
    
    <xsl:template match="Group">
        <xsl:value-of select="." />
        <xsl:text>, </xsl:text>
        <br/>
        <xsl:apply-templates select="/Result/Act/Sample/Analysis/AnalysisResult[../Group = current()]" />
    </xsl:template>
    
    <xsl:template match="AnalysisResult">
        <xsl:value-of select="Value" />
    </xsl:template>
    
</xsl:stylesheet>