Weil 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:
<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>
Meine gewünschte HTML Ausgabe soll dann so aussehen:
user.html:
<ul class="attributes">
<li id="email">Test3</li>
<li id="forename">Test</li>
<li id="surname">NeuerTester</li>
</ul>
<ul class="groups" style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/groups/">
<li class="groupRef">1</li>
<li class="groupRef">2</li>
</ul>
<ul class="outbox" style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/outbox/">
<li class="taskRef">2</li>
</ul>
<ul class="inbox" style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/inbox/">
<li class="taskRef">2</li>
</ul>
<ul class="created" style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/created/">
<li class="taskRef">1</li>
<li class="taskRef">2</li>
</ul>
</li>
Um also so eine Ausgabe zu erreichen benutze ich folgendes Script:
user.xsl:
<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 class="groupRef"><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 class="taskRef"><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 class="taskRef"><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 class="taskRef"><xsl:value-of select="taskId"/></li>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
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 ist:
sarissa - eine JS Implementierung von XSLT
Die XSL Tutorials von TopXML
XML/XSL Tutorials von DrWeb
und zu guter Letzt:
Die XML/XSL Tutorials von den W3Schools
Blogged with Flock
Comments (1)
Cooler Artikel, werde ich mir merken.
Posted by Tim | January 9, 2008 8:45 PM
Posted on January 9, 2008 20:45