XSLT – Exkurs
ToolingWeil ichs mal in Erwägung gezogen habe, aber Abstand davon genommen habe, da es eine wirklich nützliche XSLT Lib für JavaScript nocht nicht gibt.
Das Problem ist, dass man XML Daten bekommt (so wie das bei mir der Fall ist), aber diese Daten zum Beispiel als HTML Inseln (siehe letzter Post) in seinen DOM Baum “einhängen” möchte.
Man könnte sich ja jetzt fragen, wieso man dann nicht gleich HTML als Ausgabeformat nutzen möchte, aber letztendlich soll es ja alles schön kompatibel zu anderen Client bleiben und ich denke mal, dass das von mir gewünschte Format alles andere als Standard wäre. Es fehlt also eine Anweisung, um XML in das gewünschte HTML Format zu überführen. Genau das bietet einem XSLT (Extensible Stylesheet Language Transformation).
Hierbei wird durch ein XSL-Script fest gelegt, welche Daten wo im Ausgabeformat (in meinem Fall also HTML) landen sollen.
Also nehmen wir folgendes XML File:
user.xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <user uri="http://localhost:8080/cotodo/resources/users/3/"> <email>Test3</email> <forename>Test</forename> <surname>NeuerTester</surname> <userId>3</userId> <created uri="http://localhost:8080/cotodo/resources/users/3/tasks/"> <taskRef uri="http://localhost:8080/cotodo/resources/users/3/tasks/1/"> <taskId>1</taskId> </taskRef> <taskRef uri="http://localhost:8080/cotodo/resources/users/3/tasks/2/"> <taskId>2</taskId> </taskRef> </created> <groups uri="http://localhost:8080/cotodo/resources/users/3/groups/"> <groupRef uri="http://localhost:8080/cotodo/resources/users/3/groups/1/"> <groupId>1</groupId> </groupRef> <groupRef uri="http://localhost:8080/cotodo/resources/users/3/groups/2/"> <groupId>2</groupId> </groupRef> </groups> <inbox uri="http://localhost:8080/cotodo/resources/users/3/tasks/"> <taskRef uri="http://localhost:8080/cotodo/resources/users/3/tasks/2/"> <taskId>2</taskId> </taskRef> </inbox> <outbox uri="http://localhost:8080/cotodo/resources/users/3/tasks/"> <taskRef uri="http://localhost:8080/cotodo/resources/users/3/tasks/2/"> <taskId>2</taskId> </taskRef> </outbox> </user>
Wie man gut erkennt, eine – recht tief – verschachtelte Ansammlung von Datenblöcken. Wichtig für REST sind zum Beispiel auch die Referenzen auf die verschiedenen Objekte (URIs), um ggf. Objekte vollständig nach zuladen.
Meine gewünschte HTML Ausgabe soll dann so aussehen:
user.html:
<li id="3" uri="http://localhost:8080/cotodo/resources/users/3/"> <ul> <li id="email">Test3</li> <li id="forename">Test</li> <li id="surname">NeuerTester</li> </ul> <ul style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/groups/"> <li>1</li> <li>2</li> </ul> <ul style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/outbox/"> <li>2</li> </ul> <ul style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/inbox/"> <li>2</li> </ul> <ul style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/created/"> <li>1</li> <li>2</li> </ul> </li>
Es handelt sich letztendlich um ein Listenelement (welches dann in einer users Liste landet), welches weitere Unterlisten enthält. Die Anzahl der Referenzen habe ich – zur optimierten Platzausnutzung und zur Übersichtlichkeit – verringert. Letztendlich reicht mir eine Referenz der Liste und kann dann mit Hilfe der RefIds auf die URIs der einzelnen Elemente zugreifen. Das display:none habe ich nur aus dem Grund eingefügt, dass gewisse Elemente nicht sichtbar sein müssen. Mir reicht, dass sie im DOM hinterlegt sind.
Um also so eine Ausgabe zu erreichen benutze ich folgendes Script:
user.xsl:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <xsl:template match="/"> <xsl:element name="li"> <xsl:attribute name="class">user</xsl:attribute> <xsl:attribute name="id"><xsl:value-of select="user/userId" /></xsl:attribute> <xsl:attribute name="uri"><xsl:value-of select="user/@uri" /></xsl:attribute> <xsl:element name="ul"> <xsl:attribute name="class">attributes</xsl:attribute> <li id="email"><xsl:value-of select="user/email"/></li> <li id="forename"><xsl:value-of select="user/forename"/></li> <li id="surname"><xsl:value-of select="user/surname"/></li> </xsl:element> <xsl:element name="ul"> <xsl:attribute name="class">groups</xsl:attribute> <xsl:attribute name="style">display:none</xsl:attribute> <xsl:attribute name="uri"><xsl:value-of select="user/@uri" />groups/</xsl:attribute> <xsl:for-each select="user/groups/groupRef"> <li><xsl:value-of select="groupId"/></li> </xsl:for-each> </xsl:element> <xsl:element name="ul"> <xsl:attribute name="class">outbox</xsl:attribute> <xsl:attribute name="style">display:none</xsl:attribute> <xsl:attribute name="uri"><xsl:value-of select="user/@uri" />outbox/</xsl:attribute> <xsl:for-each select="user/outbox/taskRef"> <li><xsl:value-of select="taskId"/></li> </xsl:for-each> </xsl:element> <xsl:element name="ul"> <xsl:attribute name="class">inbox</xsl:attribute> <xsl:attribute name="style">display:none</xsl:attribute> <xsl:attribute name="uri"><xsl:value-of select="user/@uri" />inbox/</xsl:attribute> <xsl:for-each select="user/inbox/taskRef"> <li><xsl:value-of select="taskId"/></li> </xsl:for-each> </xsl:element> <xsl:element name="ul"> <xsl:attribute name="class">created</xsl:attribute> <xsl:attribute name="style">display:none</xsl:attribute> <xsl:attribute name="uri"><xsl:value-of select="user/@uri" />created/</xsl:attribute> <xsl:for-each select="user/created/taskRef"> <li><xsl:value-of select="taskId"/></li> </xsl:for-each> </xsl:element> </xsl:element> </xsl:template> </xsl:stylesheet>
Hierbei gelten folgende Regeln:
Der Zugriff auf die einzelnen Elemente erfolgt über XPath.
Also <xsl:value-of select=”user/userId” /> bedeutet, dass der Wert aus der Hirachie user/ geholt wird, welche zwischen den Tags userId steht. Möchte man auf ein Attribute zugreifen, so benutzt man das @ Zeichen. Wie z.B. bei <xsl:value-of select=”user/@uri” />.
Ich habe mich immer für die “Root” URI entschieden, weil die anderen URIs sich per Definitionem davon ableiten lassen.
Wollte man das XML Document nun direkt als HTML ausgeben haben, so fügt man in obiges Dokument unter
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
folgendes ein:
<?xml-stylesheet type="text/xsl" href="user.xsl"?>
Hierbei sollte die Datei natürlich unter dem gleichen Pfad erreichbar sein wir die user.xml. (Aus Testzwecken war das bei mir der Fall). Aber natürlich kann man auch jede andere URL angeben. Das Einbinden entspricht ungefähr dem von einer CSS Datei.
Empfehlenswert zu dem Thema sind folgende Links:
und zu guter Letzt:
Related
1 comment
Leave a ReplyCancel reply
Archives
- August 2025
- November 2023
- February 2023
- January 2023
- April 2020
- January 2018
- December 2017
- May 2017
- February 2016
- September 2015
- December 2014
- August 2014
- June 2014
- March 2014
- February 2014
- September 2013
- August 2013
- July 2013
- November 2012
- October 2012
- September 2012
- June 2012
- May 2012
- April 2012
- March 2012
- February 2012
- January 2012
- December 2011
- November 2011
- October 2011
- August 2011
- July 2011
- June 2011
- May 2011
- January 2011
- August 2010
- July 2010
- June 2010
- May 2010
- January 2010
- November 2009
- October 2009
- September 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- September 2006
- June 2006
- May 2006
- April 2006
- March 2006
- February 2006
- January 2006
Cooler Artikel, werde ich mir merken.