Frage zum Sortieren mit XSL
hh
- xsl
0 Thomas J.S.0 hh0 Thomas J.S.0 hh0 Thomas J.S.0 hh
Hi, welchen Lösungsweg gibt es hierfür, habe mich schon wund gegoogelt.
<roo>
<name att="einebezeichnung"/>
<name att="eineanderebezeichnung"/>
<name att="nocheinebezeichnung"/>
</root>
es soll das Attribut att ausgegeben werden und dabei ist eine Sortierung vorzunehmen. Die Regelung für die Sortierung entnehme ich aber einer anderen xml quelle
ich wollte es so machen
<xsl:for-each select="name">
<xsl:variable name="att_wert" select="@att"/>
<xsl:variable name="stufe">
<xsl:call-tempplate name="stufe_ermitteln">
<xsl:with param name="att_uebergabe" select="$att_wert"/>
</xsl:call-template>
</xsl:variable>
<!-- Ausgabe der Stufe und Bezeichnung -->
<xsl:value-of select="$stufe"/>
xsl:text_</xsl:text>
<xsl:value-of select="$att_wert"/>
<br/>
</xsl:for-each>
Zur Zeit bekomme ich dann ein Ergebnis wie folgt:
2_einebezeichnung
1_eineanderebezeichnung
3_nocheinebezeichnung
Wie schaffe ich es nun, die Ausgabe noch sortieren zu lassen? also etwa nach der stufe so:
1_eineanderebezeichnung
2_einebezeichnung
3_nocheinebezeichnung
Bin etwas ratlos.
Hallo,
Hi, welchen Lösungsweg gibt es hierfür, habe mich schon wund gegoogelt.
es soll das Attribut att ausgegeben werden und dabei ist eine Sortierung vorzunehmen. Die Regelung für die Sortierung entnehme ich aber einer anderen xml quelleich wollte es so machen
<xsl:for-each select="name">
<xsl:variable name="att_wert" select="@att"/>
<xsl:variable name="stufe">
<xsl:call-tempplate name="stufe_ermitteln">
<xsl:with param name="att_uebergabe" select="$att_wert"/>
</xsl:call-template>
</xsl:variable><!-- Ausgabe der Stufe und Bezeichnung -->
<xsl:value-of select="$stufe"/>
auf diese Weise hat aber $stufe nie einen Wert, da fehlt noch was und genau das fehlt hier auch (zu wissen, nach welchen Regel du sotrieren wills (andere xml-quelle))
Grüße
Thomas
Hallo Thomas, die andere xml-Quelle sieht ungefähr so aus, etwas "vereinfacht" (ich hoffe das ich nichts übersehen habe) Mir ist kein anderer Lösungsweg eingefallen um das Ergebnis dann so zubekommen:
<root>
<name att="einebezeichnung"/>
<name att="eineanderebezeichnung"/>
<name att="nocheinebezeichnung"/>
<name att="undnocheinebezeichnung"/>
</root>
<root>
<einheit att1="eineanderebezeichnung" att2="einebezeichnung" rang="1"/>
<einheit att1="einebezeichnung" att2="nocheinebezeichnung" rang="1"/>
<einheit att1="einebezeichnung" att2="undnocheinebezeichnung" rang="2"/>
</root>
xsl-file
<xsl:for-each select="name">
<xsl:variable name="att_wert" select="@att"/>
<xsl:variable name="rang" select="document('quelle.xml')/einheit[@att2=$att_wert]/@rang"/>
<xsl:variable name="stufe">
<xsl:call-tempplate name="stufe_ermitteln">
<xsl:with param name="att_uebergabe" select="$att_wert"/>
</xsl:call-template>
</xsl:variable>
<!-- Ausgabe der Stufe und Rang und Bezeichnung -->
<xsl:value-of select="$stufe"/>
xsl:text_</xsl:text>
<xsl:value-of select="$rang"/>
xsl:text_</xsl:text>
<xsl:value-of select="$att_wert"/>
<br/>
</xsl:for-each>
<xsl:template name="stufe_ermitteln">
<xsl:param name="att_uebergabe"/>
<xsl:param name="counter" select="0"/>
xsl:choose
<xsl:when
test="not(document('quelle.xml')/einheit[@att1=$att_uebergabe])">
<xsl:value-of select="$counter"/>
</xsl:when>
xsl:otherwise
<xsl:call-template name="stufe">
<xsl:with-param name="att_uebergabe"
select="document('quelle')/einheit[@att2=$att_uebergabe]/@att1"/>
<xsl:with-param name="counter" select="$counter + 1"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Zur Zeit bekomme ich dann ein Ergebnis wie folgt:
2_1_einebezeichnung
1_1_eineanderebezeichnung
3_1_nocheinebezeichnung
3_2_undnocheinebezeichnung
Wie schaffe ich es nun, die Ausgabe noch sortieren zu lassen? also etwa nach der stufe so:
1_1_eineanderebezeichnung
2_1_einebezeichnung
3_1_nocheinebezeichnung
3_2_undnocheinebezeichnung
Man könnte auch alles in ein XML-Quelle schreiben, das Problem dürfte aber das gleiche sein:
<root>
<name att="einebezeichnung"/>
<name att="eineanderebezeichnung"/>
<name att="nocheinebezeichnung"/>
<name att="undnocheinebezeichnung"/>
<einheit att1="eineanderebezeichnung" att2="einebezeichnung" rang="1"/>
<einheit att1="einebezeichnung" att2="nocheinebezeichnung" rang="1"/>
<einheit att1="einebezeichnung" att2="undnocheinebezeichnung" rang="2"/>
</root>
Hallo,
Hallo Thomas, die andere xml-Quelle sieht ungefähr so aus, etwas "vereinfacht" (ich hoffe das ich nichts übersehen habe) Mir ist kein anderer Lösungsweg eingefallen um das Ergebnis dann so zubekommen:
Wie schaffe ich es nun, die Ausgabe noch sortieren zu lassen? also etwa nach der stufe so:
Nach "rang" zu sortieren ist relativ einfach:
<xsl:for-each select="name">
<xsl:sort select="document('quell.xml')/root/einheit[@att2=current()/@att]/@rang" data-type="number" />
Nach Stufe zu sortieren geht so nicht, denn die Stufe wird nur erst bei instantiieren des Templates (hier for-each) ermittelt, also erst nachdem - falls vorhanden- eine Sortierung stattgefunden hat (und sort muss als erstes Kind von for-each stehen).
Den Sinn dieses Counters verstehe ich aber trotzdem nicht wirklich.
Grüße
Thomas
Hallo Thomas,
danke für den Rang. Der Counter soll nichts anderes tun, als die ebene zu bestimmen.
Vielleicht wird es so etwas deutlicher
<root>
<name att="untertitel"/>
<name att="titel"/>
<name att="unteruntertitel2"/>
<name att="unteruntertitel1"/>
</root>
<root>
<einheit att1="untertitel" att2="unteruntertitel1" rang="1"/>
<einheit att1="titel" att2="untertitel" rang="1"/>
<einheit att1="untertitel" att2="unteruntertitel2" rang="2"/>
</root>
Also der Counter mach nichts anderes, als rekursive die ebene (stufe) zu bestimmen. Mir fällt kein anderer Weg ein.
0_titel
1_1_untertitel
2_1_unteruntertitel1
2_2_unteruntertitel2
Hallo,
danke für den Rang. Der Counter soll nichts anderes tun, als die ebene zu bestimmen.
Vielleicht wird es so etwas deutlicher
<root>
<name att="untertitel"/>
<root>
<einheit att1="untertitel" att2="unteruntertitel1" rang="1"/>
Ja, das ergibt mehr Sinn.
Also der Counter mach nichts anderes, als rekursive die ebene (stufe) zu bestimmen. Mir fällt kein anderer Weg ein.
0_titel
1_1_untertitel
2_1_unteruntertitel1
2_2_unteruntertitel2
Da wäre ein count() ganz sinnvoll:
-----------------------------------------
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/root">
<html>
<head>
<title>Untitled</title>
</head>
<body>
<xsl:for-each select="name">
<xsl:sort select="count(document('temp1.xml')/root/einheit[@att1=current()/@att])" data-type="number" />
<xsl:sort select="document('temp1.xml')/root/einheit[@att2=current()/@att]/@rang" data-type="number" />
<xsl:variable name="rang" select="document('temp1.xml')/root/einheit[@att2=current()/@att]/@rang"/>
<xsl:variable name="stufe">
<xsl:call-template name="stufe_ermitteln">
<xsl:with-param name="att_uebergabe" select="@att"/>
</xsl:call-template>
</xsl:variable>
<!-- Ausgabe der Stufe und Rang und Bezeichnung -->
<xsl:value-of select="$stufe"/>
xsl:text_</xsl:text>
<xsl:value-of select="$rang"/>
xsl:text_</xsl:text>
<xsl:value-of select="@att"/>
<br/>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template name="stufe_ermitteln">
<xsl:param name="att_uebergabe"/>
<xsl:param name="counter" select="1"/>
xsl:choose
<xsl:when test="not(document('temp1.xml')/root/einheit[@att1=$att_uebergabe])">
<xsl:value-of select="$counter"/>
</xsl:when>
xsl:otherwise
<xsl:call-template name="stufe_ermitteln">
<xsl:with-param name="att_uebergabe" select="document('temp1.xml')/root/einheit[@att2=$att_uebergabe]/@att1"/>
<xsl:with-param name="counter" select="$counter + 1"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
-------------------------------
meine Ausgabe ist:
1_1_unteruntertitel1
1_2_unteruntertitel2
2__titel
3_1_untertitel
Falls das count() nicht ausreichend ist, wäre eine Gruppierung mit key() sinnvoll.
Grüße
Thomas
Hallo Thomas, danke für die Mühe, habe es nur kurz überflogen und werde mich damit auseinandersetzten. Allerdings sollte nicht es nicht so:
1_1_unteruntertitel1
1_2_unteruntertitel2
2__titel
3_1_untertitel
sonder eher
1_titel
2_1_untertitel
3_1_unteruntertitel1
3_2_unteruntertitel2
ergeben. Aber ich werde mich gleich mal ransetzen, und schauen, ob ich es so hinbigene kann. Danke dir schon einmal.
Gruß
Holger
»