# [ XSLT ] for-each sort Problem



## kle-ben (30. Mai 2007)

[EDIT] Sry ich hab wohl auf das Falsche Forum geklickt. Kann das bitte jemand verschieben ? thx 

Hi,
ich hab da eine kleines Problem mit der XSLT-Anweisung for-each. 
Ich dachte eigentlich das ich sie verstanden hab aber anscheinend wohl nicht.

Ich hab folgende xml Datei :

```
<BUCHVERWALTUNG>
    <BUECHER>
    </BUECHER>
    <GENRES>
        <GENRE GROUP="ROMAN">
            <ID>1</ID>
            <NAME>Fantasy</NAME>
        </GENRE>
        <GENRE GROUP="ROMAN">
            <ID>2</ID>
            <NAME>Science Fiction</NAME>
        </GENRE>
        <GENRE GROUP="FACHBUCH">
            <ID>3</ID>
            <NAME>Informatik</NAME>
        </GENRE>
        <GENRE GROUP="FACHBUCH">
            <ID>4</ID>
            <NAME>Mathematik</NAME>
        </GENRE>
    </GENRES>
</BUCHVERWALTUNG>
```
Ich will jetzt die verschiedenen Gruppen ermitteln die es 
bei dem GENRE Element gibt und dann die zugehörigen
NAME Elemente sortieren. 

Das ist meine XSLT Datei dazu:

```
<?xml version='1.0'  encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/BUCHVERWALTUNG">

    <xsl:apply-templates select="GENRES" />

</xsl:template>


<xsl:template match="GENRES">

    <xsl:for-each-group select="GENRE" group-by="@GROUP">
        <xsl:sort select="current-grouping-key()"/>
    
        <xsl:call-template name="mytemp">
            <xsl:with-param name="group">
                <xsl:value-of select="current-grouping-key()"/>
            </xsl:with-param>
        </xsl:call-template>

        
    </xsl:for-each-group>

</xsl:template>

<xsl:template name="mytemp">
    <xsl:param name="group"></xsl:param>
    <xsl:value-of select="$group"/><br/>
    --------------------------------
    <xsl:for-each select="/BUCHVERWALTUNG/GENRES/GENRE" >
    s
    </xsl:for-each>



</xsl:template>


</xsl:stylesheet>
```
Im Moment werden mir 4 "s" ausgegeben wenn ich es laufen lass. 
Wenn ich jetzt ein sort an die Stelle mache bekomme ich folgende 
Fehlermeldung:


> genres.xsl (33, 1): Error: on line 33 of file:///c:/DOKUME%7E1/kle-ben/Desktop/XML/genres.xsl:;   XTTE1020: A sequence of more than one item is not allowed as the @select attribute of xsl:sort;


Ersetze ich das sort durch eine value-of Anweisung
bekomme ich 4x alle 4 Namen ausgegeben.
Das erklärt natürlich die Fehlermeldung von sort.
Aber warum ist das so?

Meine sort und value-of Anweisung sehen so aus :

```
<xsl:sort select="/BUCHVERWALTUNG/GENRES/GENRE/NAME" />
<xsl:value-of select="/BUCHVERWALTUNG/GENRES/GENRE/NAME"/>
```
Was auch sehr seltsam ist. Sollte ich nicht durch meine for-each Anweisung
bei dem Element GENRE sein ? Ich arbeite mit Stylus Studio und der sagt mir
das ich bei der Pfadangabe bei meinem Rootelement anfangen muss. 
Bei meiner for-each-group Anweisung geht es komischerweise. 

Irgendwas mach ich anscheinend noch falsch, ich hoffe jemand kann mir helfen?

Gruß Benny


----------



## kle-ben (1. Juni 2007)

Also ich hab mir jetzt mal eineinfache xml Datei gemacht
und eine xsl Datei die die Elemente sortiert und das funktioniert
wunderbar. Ich weis nicht wo der Fehler in meinem obigen code 
sein soll. Kann das vieleicht an den Templates liegen?

Wenn ich bei dem obigen Beispiel meine xsl Datei als stylesheet
in meiner xml Datei angebe und sie dann mit dem Internet Explorer
öffne bekomm ich die Fehlermeldung :



> *Das Schlüsselwort xsl:template darf  xsl:for-each-group nicht enthalten. *


Allerdings kann ich damit nicht wirklich was anfagen ..

Also irgendwie hat die Benutzung der Templates wohl eine 
Auswirkung darauf wie ich auf meine Elemente  zugreife. 

Wenn ich das "mytemp" template weglasse hab ich aber 
genau die selben Probleme.

Benny


----------



## zerix (1. Juni 2007)

Hallo,

hier ist mal ein Beispiel wie du die Genres sortiert nach dem Thema(Name) in Tabellenform(html) ohne Schleife ausgegeben werden.


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

	<xsl:template match="/">
		<html>
			<head>
				<title>Das ist ein Genre-Example</title>
			</head>
			<body>
				<xsl:apply-templates />
			</body>
		</html>
	</xsl:template>


	<xsl:template match="BUCHVERWALTUNG">
		<h3>Genre</h3>
		<table border="1">
			<xsl:apply-templates select="GENRES" />
		</table>
	</xsl:template>


	<xsl:template match="GENRES">

		<xsl:apply-templates select="GENRE">
			<xsl:sort select="NAME" data-type="text"></xsl:sort>
		</xsl:apply-templates>
	</xsl:template>

	<xsl:template match="GENRE">
		<tr>
			<td>
				<xsl:value-of select="@GROUP" />
			</td>
			<xsl:apply-templates />
		</tr>
	</xsl:template>


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

	</xsl:template>
</xsl:transform>
```

Wenn ich dich richtig verstanden hab, müsste es dich ein ganzes Stück weiter bringen.

MFG

zEriX


----------



## kle-ben (1. Juni 2007)

Hi,
danke aber das ist eine einfache Sortierung. 
Ich würde die Genres aber gerne zuvor ihren Gruppen zuordnen.
Das soll dan ungefähr so aussehn:
ROMAN:
-Fantasy
-Science Fiction
FACHBUCH:
-Informatik
-Mathematik

und dazu brauch ich die Gruppierung. 
Leider funktioniert die Sortierung nach der Gruppierung nicht mehr.


----------



## zerix (1. Juni 2007)

Hallo,

bitte schön

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

	<xsl:template match="/">
		<html>
			<head>
				<title>Das ist ein Genre-Example</title>
			</head>
			<body>
				<xsl:apply-templates />
			</body>
		</html>
	</xsl:template>


	<xsl:template match="BUCHVERWALTUNG">
		<h3>Genre</h3>
		<table border="1">
			<xsl:apply-templates select="GENRES" />
		</table>
	</xsl:template>


	<xsl:template match="GENRES">

		<xsl:apply-templates select="GENRE">
			<xsl:sort select="." data-type="text"></xsl:sort>
			<xsl:sort select="NAME" data-type="text"></xsl:sort>
		</xsl:apply-templates>
	</xsl:template>

	<xsl:template match="GENRE">
		<tr>
			<td>
				<xsl:value-of select="@GROUP" />
			</td>
			<xsl:apply-templates />
		</tr>
	</xsl:template>


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

	</xsl:template>
</xsl:transform>
```

Du kannst bei apply-templates mehrere Sortierungen angeben.

MFG

zEriX


----------



## kle-ben (1. Juni 2007)

Okay danke das funktioniert so weit.
Nur würde ich es gerne mit xml 2.0 machen und 
mit der for-each-group Funktion arbeiten. 
Kannst du mir vieleicht sagen was der Fehler bei meinem
Ansatz ist? 

Danke,

Gruß Benny


----------



## kle-ben (4. Juni 2007)

Okay ich hab das Problem gelößt, es liegt an Stylus Studio.
Der behandelt die XPathausdrücke nicht immer. 

Danke für die Beispiele.

Benny


----------

