Too Much Cookies Network

XML, XSLT und Tabellen sortieren

Sonntag, 1. Januar 2006, 00:35

Im wer-weiss-was-Forum wurde die Frage gestellt, wie man am einfachsten eine längere Liste automatisch sortieren lassen könnte. Die einfachste Möglichkeit (ganz ohne Programmierung gehts nicht) wäre natürlich, die Daten in eine Datenbank zu speichern und mittels SQL-Befehl orderby auszulesen. Dazu muss allerdings eine Datenbank auf dem Server installiert sein und eine serverseitige Sprache (CGI, ASP oder PHP) verfügbar sein. Wenn eines hiervon nicht vorhanden ist oder wenn der Aufwand für eine Tabelle zu groß ist, empfiehlt sich die Speicherung der Daten in XML-Format und der Abfrage und Darstellung mittels XSLT und XPath.

Vorab einmal mein Lösungsvorschlag:

XSLT dynamic order list

XML

XML steht für “Extensible Markup Language” und ist ein Standard zur Speicherung von Daten jeglicher Art in Form einer Baumstruktur. Ein Beispiel:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<catalog>
	<cd>
		<title>Empire Burlesque</title>
		<artist>Bob Dylan</artist>
		<country>USA</country>
		<company>Columbia</company>
		<price>10.90</price>
		<year>1985</year>
	</cd>
</catalog>

Beispiel sehen

XSLT

Mit XSLT lassen sich XML-Dokumente auf relativ einfache Art und Weise formatieren. Wer sich mit XSLT vertraut machen will, kann sich das Tutorial auf w3schools.com antun. Für mein Beispiel reicht eine kleine Auswahl der Daten und eine Sortierung

<?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="/">
	<h2>My CD Collection</h2>
	<table border="1">
	<tr bgcolor="#9acd32">
		<th align="left">Title</th>
		<th align="left">Artist</th>
		<th align="left">Country</th>
		<th align="left">Company</th>
		<th align="left">Price</th>
		<th align="left">Year</th>
	</tr>
	<xsl:for-each select=”catalog/cd”>
	<xsl:sort select=”artist” order=”ascending” />
	<tr>
		<td><xsl:value-of select=”title”/></td>
		<td><xsl:value-of select=”artist”/></td>
		<td><xsl:value-of select=”country”/></td>
		<td><xsl:value-of select=”company”/></td>
		<td><xsl:value-of select=”price”/></td>
		<td><xsl:value-of select=”year”/></td>
	</tr>
	</xsl:for-each>
	</table>
</xsl:template>
</xsl:stylesheet>

Um eine XSL Transformation auf eine XML-Datei anzuwenden, gibt es die Möglichkeit, einen entsprechenden Eintrag in die XML-Datei vorzunehmen:

<?xml-stylesheet type="text/xsl" href="struct.xsl"?>

Beispiel ansehen (Firefox macht das scheinbar nicht ohne weiteres mit…)

XSL Transformation in Laufzeit

Es gibt ausserdem die Möglichkeit, XSL Transformationen in Laufzeit einer Internetseite auf eine beliebige XML-Struktur anzuwenden. Dazu bietet der Internet Explorer die Methode transformNode() an. Im Beispielcode werden sowohl die XML-Daten als auch die XSLT-Struktur nach Laden der Seite nachgeladen.

	if (isIE) {
		// Load XML
		xml = new ActiveXObject("Microsoft.XMLDOM");
		xml.async = false;
		xml.load("data.xml");

		// Load XSL
		xsl = new ActiveXObject("Microsoft.XMLDOM");
		xsl.async = false;
		xsl.load("struct.xsl");

		// Transform
		output = xml.transformNode(xsl);
	}

Firefox unterstützt weder das ActiveXObject noch die Methode transformNode(). Dafür hat Firefox (und Mozilla natürlich) das Objekt XSLTProcessor:

	if (isNav) {
		//for mozilla/netscape
		processor = new XSLTProcessor();
		xslt = document.implementation.createDocument("", "", null);
		xslt.async = false;
		xslt.load("struct.xsl");
		processor.importStylesheet(xslt);

		src_doc = document.implementation.createDocument("","", null);
		src_doc.async = false;
		src_doc.load("data.xml");

		result = processor.transformToDocument(src_doc);
		xmls = new XMLSerializer();
		output = xmls.serializeToString(result);
	}

Dynamische Sortierung mittels XML und XSLT

Was noch fehlt ist eine Methode, die die XSLT-Struktur in Laufzeit zu verändern, so dass nach einem anderen Parameter sortiert wird. Dazu soll die Funktion changeorder() da sein. Da die XSLT-Struktur genauso wie XML durchsuchbar ist, können hier die Funktionen getElementsByTagName() von Nutzen sein. Eine Besonderheit: Da xsl in einem anderen Namespace abgelegt ist, muss eigentlich die Funktion getElementsByTagNameNS() verwendet werden. Firefox unterstützt sie (GetElementsByTagNameNS(XMLNS, "sort");), Internet Explorer natürlich nicht! Im Internet Explorer übergibt man einfach die Namespace mit dem Tagname: GetElementsByTagName("xsl:sort"); Wenn man nun das sort-Element referenziert hat, muss nur noch das Attribut select auf den neuen Wert geändert werden und die Transformation erneut auf die noch gespeicherten Daten angewandt werden. Um abwechselnd aufwärts und abwärts zu sortieren, entscheidet die Funktion decide anhand der vorherigen Sortierung.

Conclusion

Das wars dann auch schon. Die einmal geladenen Daten können im Browser sooft wie nötig umsortiert werden, ohne dass eine Verbindung zum Server vonnöten wäre. Das ganze kann noch erheblich komplexer werden, indem nach bestimmten Feldern gesuch oder gar gruppiert wird. Ich hoffe Ursula vom wer-weiss-was-Forum kann hiermit was anfangen..

Was lernen wir: Statt Geister zu verjagen, kann man seine Zeit recht gut nutzen, indem man sich neue Techniken anschaut. Mit XSLT werd ich mich noch ein Weilchen beschäftigen, mal sehen, was man noch alles damit machen kann…

1 Kommentar

Pingback von Too Much Cookies Network » Dynamic Sorting of HTML-tables via XSLT

Made Sonntag, 27 of August , 2006 at 22:52

[...] Tabellen sortieren mit XSLT [...]

Kommentar hinterlassen

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

About

Seit November 2004 berichtet 'Too Much Cookies Network' live und radikal aus der Parallelgesellschaft. Die Themenwahl ist willkürlich, der Sprachstil filigran und der Gegner unklar. Zum Netzwerk gehören weiterhin folgende Seiten: