1
votes

I've gotten XSLT 2.0 grouping to work, but I'm having trouble with XSLT 1.0.

XML

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE cataleg SYSTEM "cataleg.dtd">
<?xml-stylesheet href="cataleg.css" ?>
<?xml-stylesheet type="text/xsl" href="cataleg.xsl" ?>

<cataleg>

    <peli ordre="X">
        <titol>X-Men</titol>
        <caratula>XMen.jpg</caratula>
    </peli>
    <peli ordre="B">
        <titol>X-Men 2</titol>
        <caratula>XMen2.jpg</caratula>
    </peli>
    <peli ordre="C">
        <titol>X-Men: La Decisió Final</titol>
        <caratula>XMenFD.jpg</caratula>
    </peli>
    <peli ordre="A">
        <titol>X-Men Origins: Wolverine</titol>
        <caratula>XMenOW.jpg</caratula>
    </peli>



</cataleg>

XSLT 2.0 (working)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

<xsl:template match="/">
      <html>
        <head>
          <title>PRACTICA 1 XML</title>
          <link href="https://procomprador.com/PRACTICA/cataleg.css" rel="stylesheet" />
        </head>
        <xsl:apply-templates/>
      </html>
      </xsl:template>

<xsl:template match="cataleg">
        <div id="main">
        <xsl:for-each-group select="peli" group-by="@ordre">
        <xsl:sort select="titol"/>
            <Inicial value="{@ordre}">
            <h1><xsl:value-of select="@ordre"></xsl:value-of></h1>
                <xsl:for-each select="current-group()">
                        <div class="peli">
                        <img src="https://procomprador.com/PRACTICA/imatges/{caratula}" alt=" "/>
            </div>
                </xsl:for-each>
            </Inicial>
        </xsl:for-each-group>
        </div>
</xsl:template>


</xsl:transform>

XSLT 1.0 attempt (not working)

<xsl:key name="contacts-by-surname" match="cataleg/peli" use="titol" />

<xsl:key name="pelis-by-surname" match="peli" use="@peli" />
<xsl:template match="cataleg">
    <xsl:for-each select="peli[count(. | key('pelis-by-surname', surname)[1]) = 1]">
        <xsl:sort select="surname" />
        <xsl:value-of select="surname" />,<br />
        <xsl:for-each select="key('pelis-by-peli', peli)">
            <xsl:sort select="caratula" />
            <xsl:value-of select="caratula" /> (<xsl:value-of select="titol" />)<br />
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>
1
The preferred way of grouping in XSLT 1.0 is the Muenchian method: jenitennison.com/xslt/grouping/muenchian.html - michael.hor257k
thnx but I tried it also but I don't know how it works - SrRemy99
If you've tried it and couldn't make it work, then post your best attempt so that we can help you with it. Also, if you search here for Muenchian you will find over 1000 examples you can use to learn. - michael.hor257k

1 Answers

1
votes

Your XSLT 2.0 stylesheet groups the peli elements by their ordre attribute. If you take an XML example where some peli have the same ordre:

XML

<cataleg>
    <peli ordre="X">
        <titol>X-Men</titol>
        <caratula>XMen.jpg</caratula>
    </peli>
    <peli ordre="A">
        <titol>X-Men 2</titol>
        <caratula>XMen2.jpg</caratula>
    </peli>
    <peli ordre="X">
        <titol>X-Men: La Decisió Final</titol>
        <caratula>XMenFD.jpg</caratula>
    </peli>
    <peli ordre="A">
        <titol>X-Men Origins: Wolverine</titol>
        <caratula>XMenOW.jpg</caratula>
    </peli>
</cataleg>

and apply the following stylesheet:

XSLT 1.0

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

<xsl:key name="pelis-by-ordre" match="peli" use="@ordre" />

<xsl:template match="/cataleg">
     <html>
        <xsl:for-each select="peli[count(. | key('pelis-by-ordre', @ordre)[1]) = 1]">
            <h1>
                <xsl:value-of select="@ordre" />
            </h1>
            <xsl:for-each select="key('pelis-by-ordre', @ordre)">
                <div>
                    <xsl:value-of select="titol" /> 
                </div>
            </xsl:for-each>
        </xsl:for-each>
     </html>
</xsl:template>

</xsl:stylesheet>

you will get:

Result

<html>
<h1>X</h1>
<div>X-Men</div>
<div>X-Men: La Decisió Final</div>
<h1>A</h1>
<div>X-Men 2</div>
<div>X-Men Origins: Wolverine</div>
</html>

rendered:

enter image description here