Geschrieben von: Frederic Ganner
Kategorie: XML
This printed page brought to you by AlphaSierraPapa
Bei der Datenspeicherung und besonders beim Datenaustausch rückt XML immer mehr in den Vordergrund. Damit die Anwendung (oder der Mensch) mit der wir Daten austauschen diese auch aufnehmen kann, müssen diese meist aufbereitet werden - in ein Zielformat "transformiert" werden. Hierzu gibt es die eXtended Stylesheet Language (XSL). Und daß diese weit mehr kann (und für weit mehr gedacht ist) als ein XML-File in HTML zu verwandeln, möchte ich heute vermitteln.
Zunächst werden wir uns XSL im Allgemeinen zuwenden, um dann anhand von praktischen Beispielen die Verwendung von XSLT, der eXtended Stylesheet Language for Transformations, zu erlernen, und zu verstehen wie sich in einer ASP-Umgebung Stylesheets einbinden lassen. Um am Server mit XSL arbeiten zu können, müssen natürlich die Microsoft XML Core Services (MSXML 4.0 oder höher) installiert sein.
Die W3C-Spezifikation von XSL beschreibt eine Sprache zur Transformation und Formatierung von Dokumenten. Die folgende Grafik beschreibt grundsätzlich wie eine XML-Datei mit einem Stylesheet vom XSLT-Prozessor verarbeitet wird. Das Ergebnis der Verarbeitung kann eine XML-, HTML-, oder irgendein Textformat sein, zum Beispiel Comma Separated Values (CSV).
Neben der Umwandlung strukturierter Daten durch XSLT zählt zu XSL auch der Bereich Formatting Objects, die zum Beispiel für Printformate verwendet werden. XSLT bildet also einen Teilbereich der XSL-Empfehlung.
Der dritte wichtige Teil von XSL ist die XML Path Language, kurz XPath. XPath ist eine Sprache die, bei der Verarbeitung von Dokumenten durch XSLT, dem Programmierer die nötigen Werkzeuge bereitstellt, um die Daten nicht nur auszuzeichnen, sondern auch komplexe Veränderungen an ihnen vorzunehmen. Im Kontext von XSLT wird diese Sprache hauptsächlich dazu verwendet, um Elemente zu adressieren und Zeichenketten oder Zahlen zu manipulieren.
Oft wird auch nach dem Unterschied von XSL zu Cascading Style Sheets gefragt. XSL bietet eine komplette Sprache um Dokumente umfassend zu manipulieren, dagegen beschränkt sich CSS auf die Auszeichnung von Elementen, zum Zweck der einfachen Darstellung im Browser
Der wichtigste Punkt zum Verständnis der Funktionsweise von XSLT ist, daß die Abarbeitung der XSLT-Datei nicht prozedural ist. Es wird also nicht jedes Element nach seinem Vorkommen in der Datei bearbeitet, sondern sowohl die XSLT-Datei als auch das XML-File werden vom MSXML zu DOM-Trees geparsed. Diese Herangehensweise ermöglicht es zu jedem Zeitpunkt der Laufzeit auf alle Elemente und Daten zuzugreifen, und nur das ermöglicht letztendlich umfangreiche Formatierungen.
Der Parser selbst akzeptiert deshalb auch nicht ausschließlich XML-Files, sondern kann mit jedem beliebigen DOM-Dokument gefüttert werden, und kann ebenso DOM-Dokumente an andere Anwendungen weitergeben.
Der Parser hat während der Ausführung zwei DOM-Dokumente gespeichert. Das eine besteht aus einer Baumstruktur dessen Nodes mit den Elementen der XML-Datei gefüllt sind, das andere besteht analog dazu aus einer Baumstruktur der Formatierungsanweisungen die die XSLT-Datei vorgibt. Diese Anweisungen sind sogenannte Template Rules. Die folgende Grafik zeigt anhand eines Abschnitts einer XSLT-Datei die grundsätzliche Funktion einer Template-Regel:
Wenn der Parser auf diese Regel stößt, durchsucht er das gesamte XML-Dokument nach Elementen die auf das
Suchmuster, auch Pattern genannt, passen. In diesem Fall wäre das ein "<autor>"-Element. Sofern der Parser ein
Element, auf das der Pattern zutrifft, findet, fügt er das Template dem Output-Stream hinzu. Im gezeigten Beispiel würde
ein "<Name<"-Element mit dem Inhalt des Elements "
Der ganze Verarbeitungsprozess besteht aus einem Suchen von Elementen und einem Anfügen der entsprechenden Templates an den Output. Um Daten in die entstehende Datei zu übernehmen, müssen diese explizit angegeben und verarbeitet werden. Wenn für Elemente des bearbeiteten XML-Files keine Templates vorhanden sind, kommen sie im Output-Dokument auch nicht vor.
Der Pattern "autor" war auch schon unsere erste Begegnung mit XPath, denn alle Suchmuster in XSLT sind XPath Syntax. Mit XPath kann man sich durch den XML-Tree navigieren, und die Elemente auswählen, und verändern, die man in das neu entstehende Dokument aufnehmen will. Das folgende Beispiel zeigt eine einfache XML Datei, auf die sich die weiteren Erklärungen der XPath Syntax beziehen werden.
<?xml version="1.0" ?> <?xml-stylesheet type="text/xsl" href="sample.xsl" ?> <!-- Kunden mit Namen und ID --> <Kunden> <Kunde id="45325"> <Name>Meier</Name> <Vorname>Peter</Vorname> <Umsatz>1423</Umsatz> <Kaeufe>28</Kaeufe> </Kunde> <Kunde id="45326"> <Name>Schmidt</Name> <Vorname>Harald</Vorname> <Umsatz>7421.00</Umsatz> <Kaeufe>19</Kaeufe> </Kunde> <Kunde id="45327"> <Name>Weinberg</Name> <Vorname>Simon</Vorname> <Umsatz>5742.94</Umsatz> <Kaeufe>23</Kaeufe> </Kunde> <Kunde id="45328"> <Name>Franz</Name> <Vorname>Gans</Vorname> <Umsatz>3650</Umsatz> <Kaeufe>15</Kaeufe> </Kunde> </Kunden>
Mit folgender Template Rule werden durch das "value-of"-Tag einzelne Werte aus der XML Datei extrahiert. Durch XPath Ausdrücke können dabei genau die gewünschten Elemente mit dem Attribut "select" angesteuert werden.
<xsl:template match="/"> <xsl:value-of select="Kunden/Kunde[2]/@id" /> <xsl:value-of select="/Kunden/Kunde/Name | Kunden/Kunde/@id" /> <xsl:value-of select="/*/Kunde[@id > '45326']/Name" /> <xsl:value-of select="//node()" /> <xsl:value-of select="processing-instruction() | comment()" /> </xsl:template>
Im folgenden Screenshot sieht man das Ergebnis des Listings. Zum besseren Verständnis sind in der HTML-Seite sowohl die Ausgaben der obigen Elemente als auch die Tags selbst dargestellt. Außerdem ist zu beachten, daß mit einem "value-of"-Tag immer nur der erste Werte der angewählten Elemente ausgegeben wird. Möchte man mehrere Werte anzeigen, müssen dazu Schleifen verwendet werden.
Das "match" Attribut der Template Rule legt den Kontext des Templates fest. Ein "/" setzt den Cursor auf die Root Node, deshalb können bis ein neuer Kontext gesetzt wird alle Pfade relativ zu diesem angegeben werden. Im ersten select-Attribut ist der Pfad relativ, da kein "/" am Anfang steht. Im zweiten dagegen ist der Pfad durch den Schrägstrich, unabhängig vom Kontext, absolut gesetzt.
Die "2" in den eckigen Klammern des ersten Ausdrucks verweist auf das zweite von mehreren gleichen Elementen. Um auf die Attribute der Elemente zugreifen zu können, wird ein "@" verwendet. Das dritte Tag beginnt mit dem "*", der für einen beliebigen Wert steht. Welche der drei Schreibweisen verwendet wird, um zu dem Element "Kunde" zu gelangen, ist in diesem Fall egal. Die Funktion "node()" gibt alle Nodes zurück, die durch die Pfadangabe erreichbar sind.
Durch die vielen Möglichkeiten auf Objekte zuzugreifen gibt es in XPath oft viele Wege zum gleichen Ziel. Der zweite Ausdruck verfügt noch über einen Trennungsstrich, dem eine zweite Anweisung folgt. Diese Konstruktion sagt dem Prozessor: Wähle alle Elemente aus, die von einem oder von beiden Ausdrücken angewählt werden. Der Ausdruck in den eckigen Klammern des dritten Elements hat zum Ergebnis, daß nur Kunden mit einer Kundennummer höher als "45326" ausgewählt werden. In eckigen Klammern stehen demnach immer Beschränkungen oder Ausdrücke die eine Anwahl präzisieren. Der letzte Ausdruck gibt die Processing Instructions, und die Kommentare die an die Root Node anghängt sind zurück.
Die zwei Slashes vor dem Aufruf der "node()"-Funktion schränken die Funktion auf die aktuelle Node und die darunterliegenden ein. Zwei Schrägstriche verweisen auf die Kontextnode und auf alles unterhalb. Anstelle der aktuellen Node könnte man einfach einen Punkt verwenden ("."). Zwei Punkte in einem Pfad würden auf die darüberliegende Ebene verweisen. Diese Zeichenfolgen sind eigentlich Kurzschreibweisen der Achsen-Ausdrücke von XPath, die eine Node und eine Richtung mit weiteren Nodes angeben. Es reicht in der Regel jedoch aus, wenn man mit den geläufigen Abkürzungen vertraut ist.
Der in den eckigen Klammern verwendete Operator ist ein ">" Zeichen. Da diese Entity auch von XML verwendet wird, muß sie umgeschrieben werden. Die Umschreibungen der Zeichen sind zwar meistens die, die man auch in HTML verwendet, jedoch gibt es Ausnahmen wie zB. die Leerstelle die als   geschrieben werden muß (analog dazu: Carriage Return " ", Tab "	", Newline " ").
Mit diesem grundsätzlichen Wissen über die Verwendung von XPath kann man bereits beginnen XSL Stylesheets zu schreiben. Um allerdings komplexe Formatierungen durchzuführen, benötigt man natürlich noch einfache Konstrukte wie "if then", das in XSLT "when otherwise" heißt, und "for each", sowie weitergehende Funktionen die die Behandlung der Daten ermöglichen.
Neben den Möglichkeiten Elemente zu finden und zu adressieren bietet XPath auch eine Reihe von Funktionen, die das Formatieren von Elementen erleichtern, und Informationen über Daten liefern. Die wichtigsten vier sind hier zusammengefasst:
<xsl:template match="/"> <xsl:value-of select="format-number(Kunden/Kunde/Zahl,'####,000')"/> <xsl:value-of select="sum(Kunden/Kunde/Zahl)"/> <xsl:value-of select="round(Kunden/Kunde[@='45327']/Zahl)"> <xsl:value-of select='substring("zerhackt", 4, 7)'/> </xsl:template>
Die Funktion "format-number()" verlangt zum einen ein Element dessen Inhalt eine Zahl ist, zum anderen die Vorgabe wie die Zahl zu formatieren ist. Die Rauten stehen dabei für Integer, die 0 für eine Stelle die mit 0 belegt wird wenn sie nicht durch einen Integer belegt werden kann.
Die "sum()" Funktion gibt die Summe aller Zahl-Elemente zurück. Wie zu erwarten rundet "round()" den übergebenen Parameter. Durch "substring()" wird ein Teil eines Strings zurückgegeben, die erste Stelle hat dabei den Index "1". Das Beispiel gibt demnach den String "hack" zurück.
Im folgenden Code-Abschnitt wird ein Beispiel für die Verwendung einer Schleife, einer Variable und der Funktion "count()" gegeben.
<xsl:template match="/"> <xsl:for-each select="/Kunden/Kunde[not(Umsatz < 5000)]"> <xsl:choose> <xsl:when test="number(//Kaeufe <= 20)"> schlecht </xsl:when> <xsl:otherwise> gut </xsl:otherwise> </xsl:choose> </xsl:for-each> <xsl:variable name="Anzahl_Kunden" select="/Kunden/Kunde"/> <xsl:value-of select="count($Anzahl_Kunden)"/> </xsl:template>
Das obige Tempate beinhaltet eine "for-each"-Schleife. Die Schleifenbedingung wird in dem "select"-Attribut des öffnenden "for-each"-Elements formuliert. Im Beispiel werden alle "Kunde"-Elemente mit dem Schleifeninhalt verarbeitet, bei denen der Inhalt des "Umsatz"-Elements größer als 5000 ist. Die verwendete Funktion "not()" gibt "true" zurück, wenn das übergebene Argument "false" ergibt.
In der Schleife wird durch das "choose"-Element eine "when-otherwise"-Bedingung eingeleitet. Das Attribut "test" des Elements "when" enthält die Bedingung des Statements. Um sich Arbeit zu ersparen gibt es natürlich auch die Möglichkeit Variablen zu definieren. Eine solche kann in XSLT durch das "variable"-Element erstellt werden. Die obige Variable enthält ein Node-Set, ein Array von Elementen, aller "Kunde"-Elemente. Eine definierte Variable steht immer in dem Kontext den das Template, in dem sie erstellt wird, vorgibt.
Bei der relativen Angabe von Pfaden ist also zu beachten wo in der Baumstruktur sich das Template befindet. Das folgende Element bezieht sich auf diese Variable und schreibt über die Funktion "count()" die Anzahl aller vorkommenden "Kunde"-Elemente in den Output-Stream.
Wenn man in ASP mit XSL arbeitet, werden einem simple Möglichkeiten des Parsers zur Verfügung gestellt, die Stylesheets in bestehende Anwendungen einzubinden. Ein häufiger Anwendungsfall des DOMs ist, eine XML-Datei zu erstellen, um diese dann einer Anwendung zu übergeben. Anstatt dem User und der Anwendung die selbe XML-Datei vorzusetzen, könnte man einerseits das "rohe" XML speichern, dem Benutzer dagegen eine aufbereitete HTML-Datei zusenden.
Für solche Fälle gibt es den IXSL-Processor. Wie ein DOM-Dokument wird zuerst ein XSL-Template-Objekt als Server-Objekt instanziert. Diesem wird dann ein Stylesheet zugewiesen, und mit der Methode ".CreateProcessor()" wird der XSL-Prozessor erstellt. Über die Eigenschaft "Input" kann diesem ein DOM-Dokument zugewiesen werden. Nach der Verarbeitung durch den ".Transform()"-Aufruf steht unter ".Output" der transformierte Inhalt parat. Selbigen schreibt man dann nach Gusto entweder gleich in den Output Stream oder man speichert ihn im Lieblingsformat ab.
Die Beispiel-Datei Transform.asp wird die Datei products.xml in folgende anregende Darstellung verwandeln. Diese könnte dann zum Beispiel auch als Mail versendet werden:
So sieht die zugrundeliegende XML-Datei aus:
<?xml version="1.0" ?> <?xml-stylesheet type="text/xsl" href="products.xsl" ?> <Statistik> <Info> <Inhalt>Verkaufszahlen</Inhalt> <Von>10.11.2000</Von> <Bis>10.11.2001</Bis> </Info> <Software> <Produkt id="03485"> <Name>Mailbuster</Name> <System>WIN</System> <Preis>350</Preis> <Sold quartal1="146" quartal2="163" quartal3="157" quartal4="143"></Sold> </Produkt> <Produkt id="03478"> <Name>Personnel Firewall</Name> <System>WIN</System> <Preis>90</Preis> <Sold quartal1="751" quartal2="760" quartal3="694" quartal4="708"></Sold> </Produkt> <Produkt id="03490"> <Name>Filtering Smart</Name> <System>UNX</System> <Preis>890</Preis> <Sold quartal1="147" quartal2="269" quartal3="375" quartal4="512"></Sold> </Produkt> <Produkt id="03417"> <Name>Final Sniff</Name> <System>UNX</System> <Preis>120</Preis> <Sold quartal1="245" quartal2="241" quartal3="230" quartal4="259"></Sold> </Produkt> <Produkt id="03450"> <Name>Space Panic</Name> <System>WIN</System> <Preis>60</Preis> <Sold quartal1="156" quartal2="123" quartal3="138" quartal4="154"></Sold> </Produkt> </Software> </Statistik>
Aufgrund der Größe ist das Stylesheet product.xsl unter folgendem Link zu finden: products.xsl
Wie oben beschrieben findet in der Transform.asp die Verarbeitung durch den IXSL-Processor statt. Das Ergebnis wird "on the fly" in den Output geschrieben. Hier das vollständige Script:<% @Language = "VBScript" %> <% Set XSLTMP = Server.CreateObject("Msxml2.XSLTemplate.4.0") Set XSLDOK = Server.CreateObject("Msxml2.FreeThreadedDOMDocument.4.0") XSLDOK.Async = false XSLDOK.Load(Server.MapPath("products.xsl")) XSLTMP.Stylesheet = XSLDOK Set XMLDOK = Server.CreateObject("Msxml2.DOMDocument.4.0") XMLDOK.Async = false XMLDOK.Load(Server.MapPath("products.xml")) Set XSLPU = XSLTMP.CreateProcessor() XSLPU.Input = XMLDOK XSLPU.Transform() Response.Write(XSLPU.output) %>
Wie man sehen kann ist der letztendlich entstehende ASP-Code sehr kurz, da die eigentliche Arbeit von der XSL-Datei verrichtet wird. Wenn man die Formatierung der XML-Daten nicht mehr in der ASP-Datei vornimmt, hat das eben auch den Vorteil, daß Anpassungen der Formatierungen sehr leicht in einer XSL-Datei vorgenommen werden können, und nicht in jeder einzelnen ASP-Datei.
XSL is here to stay. Die Möglichkeiten XML zu verarbeiten sind vielfältig, durchsetzen werden sich aber letztendlich nur die, die am breitesten und von den meisten Plattformen unterstützt werden. Als W3C-Standard erfüllt XSL genau dieses Kriterium. XSL wird in XML-Syntax geschrieben, in diese Richtung bewegen sich auch Technologien wie CSS. Diese Nähe zu XML macht XSL über kurz oder lang zum idealen Werkzeug um den Datenaustausch von Menschen und Anwendungen, das Haupteinsatzgebiet von XML, abzuwickeln.
This printed page brought to you by AlphaSierraPapa
Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20020116.zip
Arbeiten mit dem SQL Server XML View Mapper
http:/www.aspheute.com/artikel/20020416.htm
Auslesen von XML Dateien mit dem DOM
http:/www.aspheute.com/artikel/20000417.htm
C# XML-Kommentare — Dokumentation von selbst
http:/www.aspheute.com/artikel/20020730.htm
Erstellen von XML-Dateien mit dem DOM
http:/www.aspheute.com/artikel/20011116.htm
Verwendung von XML-Schemas (XSD)
http:/www.aspheute.com/artikel/20010925.htm
Was sind XML Schemas?
http:/www.aspheute.com/artikel/20010514.htm
Deutsche XSLT Kurzreferenz (PDF)
http://www.diprogmbh.de/download/XSLT.pdf
MS XSL to XSLT Converter for XSLT compliance
http://msdn.microsoft.com/msdn-files/027/000/540/xsl-xslt-converter.exe
MSDN XML Core
http://msdn.microsoft.com/xml/
Umfassende XSLT Referenz von topxml.com
http://www.topxml.com/xsl/xsltref.asp
XPath Visualiser for checking XPath Queries
http://www.vbxml.com/downloads/files/xpathvisualiserseptember.zip
XSL Lint semantic Checker for XSLT
http://nwalsh.com/xsl/xslint/
XSL Seite des W3C
http://www.w3.org/Style/XSL/
©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.