{"id":55001047,"date":"2016-08-01T00:00:00","date_gmt":"2020-05-22T18:42:33","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1047"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"XMLDokumente_transformieren_mit_XSLT","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/","title":{"rendered":"XML-Dokumente transformieren mit XSLT"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg09.met.vgwort.de\/na\/638c857edf2b43e6ae49f4919dfbde07\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Mit den eingebauten Funktionen f&uuml;r den Export von Daten aus Tabellen und Abfragen in das XML-Format k&ouml;nnen Sie bereits recht gute Ergebnisse erzielen. Nat&uuml;rlich k&ouml;nnen Sie aber nicht komplett steuern, wie das Zieldokument sp&auml;ter aussehen wird. Je nach den Anforderungen der Anwendung, die das XML-Dokument weiterverarbeiten soll, sind noch &auml;nderungen notwendig. Hier tritt die Transformation von XML-Dokumenten auf den Plan: Mit einer sogenannten .xslt-Datei legen Sie fest, wie ein Dokument in ein anderes umgeformt werden soll. Den vollst&auml;ndigen Vorgang steuern Sie dann per VBA-Prozedur. Dieser Beitrag liefert die Grundlagen der Transformation und die notwendigen VBA-Techniken.<\/b><\/p>\n<h2>Voraussetzungen<\/h2>\n<p>Wenn Sie mit den eingebauten Export-Funktionen einfach nur XML-Dokumente auf Basis von Tabellen oder Abfragen erstellen wollen, ben&ouml;tigen Sie dazu keine weiteren Bibliotheken. Auch eine Transformation eines exportierten XML-Dokuments &uuml;ber die entsprechende Funktion der Benutzeroberfl&auml;che (zum Beispiel &uuml;ber den Ribbon-Eintrag <b>Externe Daten|Exportieren|XML-Datei<\/b>) k&ouml;nnen Sie ohne weitere Hilfsmittel durchf&uuml;hren &#8211; Sie k&ouml;nnen einfach im Assistenten angeben, welche <b>.xslt<\/b>-Datei die Vorgaben f&uuml;r die Transformation enth&auml;lt. Das erzeugte XML-Dokument wird dann nach dem Export automatisch auf Basis dieser Datei transformiert. Sollten Sie jedoch einen Export mit der Methode <b>ExportXML <\/b>des <b>Application<\/b>-Objekts durchf&uuml;hren wollen, k&ouml;nnen Sie die <b>.xslt<\/b>-Datei dort nicht etwa per Parameter angeben. Sie exportieren die Daten dort erst in ein XML-Dokument und f&uuml;hren dann die Transformation durch. F&uuml;r diese Transformation ben&ouml;tigen Sie Objekte und Methoden der Bibliothek <b>Microsoft XML, vx.0<\/b>, wobei Sie die jeweils aktuellste Version dieser Bibliothek w&auml;hlen sollten (s. Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_04\/pic_1047_001.png\" alt=\"Verweis auf die Bibliothek Microsoft XML, v6.0\" width=\"424,6255\" height=\"334,748\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Verweis auf die Bibliothek Microsoft XML, v6.0<\/span><\/b><\/p>\n<h2>Transformations-Grundlagen<\/h2>\n<p>XML-Dokumente bestehen aus Daten und aus Elementen zur Strukturierung dieser Daten. Damit lassen sich beispielsweise die Daten aus verkn&uuml;pften Tabellen einer Datenbank hierarchisch darstellen &#8211; zum Beispiel haben Sie eine Kategorien-Tabelle und eine Artikel-Tabelle, wo jedem Artikel eine Kategorie zugewiesen ist. In einem XML-Dokument k&ouml;nnten Sie nun die Kategorien und Artikel hierarchisch strukturiert speichern:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-8\"&gt;\r\n&lt;Kategorien&gt;\r\n   &lt;Kategorie&gt;\r\n     &lt;KategorieID&gt;1&lt;\/KategorieID&gt;\r\n     &lt;Kategoriename&gt;Kategorie 1&lt;\/Kategoriename&gt;\r\n     &lt;Artikel&gt;\r\n       &lt;ArtikelID&gt;1&lt;\/ArtikelID&gt;\r\n       &lt;Artikelname&gt;Artikel 1&lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n     &lt;Artikel&gt;\r\n       &lt;ArtikelID&gt;2&lt;\/ArtikelID&gt;\r\n       &lt;Artikelname&gt;Artikel 2&lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n   &lt;\/Kategorie&gt;\r\n   &lt;Kategorie&gt;\r\n     &lt;KategorieID&gt;2&lt;\/KategorieID&gt;\r\n     &lt;Kategoriename&gt;Kategorie 2&lt;\/Kategoriename&gt;\r\n     &lt;Artikel&gt;\r\n       &lt;ArtikelID&gt;3&lt;\/ArtikelID&gt;\r\n       &lt;Artikelname&gt;Artikel 3&lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n     &lt;Artikel&gt;\r\n       &lt;ArtikelID&gt;4&lt;\/ArtikelID&gt;\r\n       &lt;Artikelname&gt;Artikel 4&lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n   &lt;\/Kategorie&gt;\r\n&lt;\/Kategorien&gt;<\/pre>\n<p>Die Elemente aus solch einem XML-Dokument k&ouml;nnen Sie mit einer entsprechenden <b>.xslt<\/b>-Datei in beliebiger Form umstrukturieren, also transformieren.<\/p>\n<p>Dazu sind nur wenige Schritte n&ouml;tig:<\/p>\n<ul>\n<li>Sie ben&ouml;tigen ein Objekt des Typs <b>DOMDocument <\/b>(oder <b>DOMDocument60<\/b>, je nach verwendeter Typ-Bibliothek &#8211; in unserem Fall <b>Microsoft XML, v6.0 <\/b>und <b>DOMDocument60<\/b>), das Sie mit dem Inhalt des zu transformierenden XML-Dokuments f&uuml;llen.<\/li>\n<li>Ein weiteres Objekt des gleichen Typs f&uuml;llen Sie mit dem Inhalt der <b>.xslt<\/b>-Datei.<\/li>\n<li>Schlie&szlig;lich brauchen Sie noch ein drittes <b>DOMDocument<\/b>-Objekt, in welchem die transformierte Datei landet.<\/li>\n<li>F&uuml;r das erste <b>DOMDocument<\/b>-Objekt f&uuml;hren Sie die Methode <b>transformNodeToObject <\/b>aus, dem Sie das zweite und das dritte <b>DOMDocument<\/b>-Objekt als Parameter &uuml;bergeben.<\/li>\n<\/ul>\n<p>F&uuml;r diese Anweisungen haben wir eine einfache Prozedur geschrieben, der Sie die Pfade f&uuml;r die drei beteiligten XML-Dokumente per Parameter &uuml;bergeben k&ouml;nnen. Diese Prozedur hei&szlig;t <b>Transformieren<\/b> und sieht wie in Listing 1 aus. Mit dem ersten Parameter &uuml;bergeben Sie den Pfad zu der zu transformierenden XML-Datei, mit dem zweiten den Pfad zur <b>.xslt<\/b>-Datei und mit dem dritten den Pfad, unter dem die transformierte Datei gespeichert werden soll.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>Transformieren(strQuelle<span style=\"color:blue;\"> As String<\/span>, strXSLT<span style=\"color:blue;\"> As String<\/span>, strZiel<span style=\"color:blue;\"> As String<\/span>, _\r\n         <span style=\"color:blue;\">Optional<\/span> strFehler<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objQuelle<span style=\"color:blue;\"> As <\/span>MSXML2.DOMDocument60\r\n     <span style=\"color:blue;\">Dim <\/span>objXSLT<span style=\"color:blue;\"> As <\/span>MSXML2.DOMDocument60\r\n     <span style=\"color:blue;\">Dim <\/span>objZiel<span style=\"color:blue;\"> As <\/span>MSXML2.DOMDocument60\r\n     <span style=\"color:blue;\">Set<\/span> objQuelle = <span style=\"color:blue;\">New<\/span> MSXML2.DOMDocument60\r\n     objQuelle.Load strQuelle\r\n     <span style=\"color:blue;\">If <\/span>objQuelle.parseError = 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> objXSLT = <span style=\"color:blue;\">New<\/span> MSXML2.DOMDocument60\r\n         objXSLT.Load strXSLT\r\n         <span style=\"color:blue;\">If <\/span>objXSLT.parseError = 0<span style=\"color:blue;\"> Then<\/span>\r\n             <span style=\"color:blue;\">Set<\/span> objZiel = <span style=\"color:blue;\">New<\/span> MSXML2.DOMDocument60\r\n             objQuelle.transformNodeToObject objXSLT, objZiel\r\n             objZiel.Save strZiel\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             Transformieren = objXSLT.parseError.errorCode\r\n             strFehler = \".xslt-datei: \" & <span style=\"color:blue;\">vbCrLf<\/span> & strXSLT & <span style=\"color:blue;\">vbCrLf<\/span> & objXSLT.parseError.reason\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         Transformieren = objQuelle.parseError.errorCode\r\n         strFehler = \"Quelldatei: \" & <span style=\"color:blue;\">vbCrLf<\/span> & strQuelle & <span style=\"color:blue;\">vbCrLf<\/span> & objQuelle.parseError.reason\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Prozedur f&uuml;r die einfache Transformation eines XML-Dokuments<\/span><\/b><\/p>\n<p>Der vierte Parameter ist ein optionaler R&uuml;ckgabeparameter, der von der Funktion mit einer Fehlermeldung gef&uuml;llt wird, wenn ein Fehler auftritt. Die Funktion deklariert dann die drei ben&ouml;tigten Objekte vom Typ <b>DOMDocument60<\/b>.<\/p>\n<p>Dann erstellt sie das erste Objekt <b>objQuelle <\/b>mit der <b>New<\/b>-Anweisung und f&uuml;llt es mit der <b>Load<\/b>-Methode. Die <b>Load<\/b>-Methode erwartet den Pfad zu einer XML-Datei, den wir mit dem Parameter <b>strQuelle <\/b>&uuml;bergeben. Hierbei kann es geschehen, dass ein Fehler auftritt &#8211; beispielsweise, dass unter dem mit <b>strQuelle <\/b>angegebenen Pfad gar keine Datei gefunden werden kann. Tritt ein solcher Fehler auf, liefert die Eigenschaft <b>parseError <\/b>von <b>objQuelle <\/b>einen Wert ungleich <b>0<\/b>. Dies pr&uuml;fen wir in einer <b>If&#8230;Then<\/b>-Bedingung, deren <b>Else<\/b>-Teil gegebenenfalls die Fehlermeldung in den R&uuml;ckgabeparameter <b>strFehler <\/b>schreibt &#8211; samt Angabe der fehlerhaften Datei. Au&szlig;erdem weist die Funktion dem R&uuml;ckgabewert der Funktion die Fehlernummer zu.<\/p>\n<p>Tritt kein Fehler auf, erstellt die Funktion das zweite Objekt <b>objXSLT <\/b>und f&uuml;llt es mit dem Inhalt der mit <b>strXSLT <\/b>angegebenen <b>.xslt<\/b>-Datei &#8211; wieder unter Verwendung der <b>Load<\/b>-Methode. Auch hier eventuell auftretende Fehler werden entsprechend behandelt.<\/p>\n<p>Ist bis hierher kein Fehler aufgetreten, erstellt die Prozedur das <b>DOMDocument60<\/b>-Objekt f&uuml;r das transformierte XML-Dokument. Die Transformation selbst erfolgt dann durch die Methode <b>transformNodeToObject <\/b>des Objekts <b>objQuelle<\/b>. Dieser &uuml;bergeben wir Verweise auf die <b>DOMDocument60<\/b>-Objekte mit der <b>.xslt<\/b>-Datei und der Zieldatei als Parameter.<\/p>\n<p>Nach erfolgter Transformation speichern wir den Inhalt des neu erzeugten und gef&uuml;llten XML-Dokuments aus <b>objZiel <\/b>mit der <b>Save<\/b>-Methode in der mit dem Parameter <b>strZiel <\/b>angegebenen XML-Datei.<\/p>\n<h2>Aufruf der Funktion &#8222;Transformieren&#8220;<\/h2>\n<p>Der Aufruf dieser Funktion kann, wenn Sie das zu transformierende XML-Dokument und das <b>.xslt<\/b>-Dokument bereits auf der Festplatte abgelegt haben, ganz einfach wie folgt geschehen:<\/p>\n<pre>Transformieren &lt;Quelldokument&gt;, &lt;XSLT-Dokument&gt;,  &lt;Zieldokument&gt;<\/pre>\n<p>So erhalten Sie zwar keinen Zugriff auf eine eventuelle Fehlermeldung, aber es ist der schnellste Weg, um die Transformation durchzuf&uuml;hren, wenn die Dateien im Dateisystem liegen.<\/p>\n<p>Wenn Sie sich die Funktionsweise inklusive Fehlermeldung ansehen m&ouml;chten, k&ouml;nnen Sie die Methode aus Listing 2 nutzen &#8211; gemeinsam mit den Tabellen der Beispieldatenbank zu diesem Beitrag. Die Methode deklariert zun&auml;chst die ben&ouml;tigten Variablen. Dann exportiert sie ein XML-Dokument auf Basis der Tabellen <b>tblKategorien <\/b>und <b>tblArtikel<\/b>, wobei die Artikeldaten den Kategorie-Elementen untergeordnet werden sollen (wie dies im Detail funktioniert, lesen Sie im Beitrag <b>XML-Export mit VBA<\/b>, <b>www.access-im-unternehmen.de\/1046<\/b>).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TestTransformieren()\r\n     <span style=\"color:blue;\">Dim <\/span>strQuelle<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strXSLT<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strZiel<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strFehler<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngFehler<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objAdditionalData<span style=\"color:blue;\"> As <\/span>AdditionalData\r\n     <span style=\"color:blue;\">Set<\/span> objAdditionalData = Application.CreateAdditionalData\r\n     objAdditionalData.Add \"tblArtikel\"\r\n     strQuelle = CurrentProject.Path & \"\\KategorienUndArtikel_Untransformiert.xml\"\r\n     Application.ExportXML acExportTable, \"tblKategorien\", strQuelle, AdditionalData:=objAdditionalData\r\n     strXSLT = CurrentProject.Path & \"\\KategorienUndArtikel.xslt\"\r\n     strZiel = CurrentProject.Path & \"\\KategorienUndArtikel_Transformiert.xml\"\r\n     lngFehler = Transformieren(strQuelle, strXSLT, strZiel, strFehler)\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> lngFehler = 0<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> strFehler\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Aufruf der Funktion Transformieren mit Beispieldaten<\/span><\/b><\/p>\n<p>Der Export landet in der Datei <b>KategorienUndArtikel_Untransformiert.xml<\/b>. Die <b>.xslt<\/b>-Datei zu diesem Beispiel finden Sie in den Download-Dateien. Sie hei&szlig;t <b>KategorienUndArtikel.xslt <\/b>und sollte sich im gleichen Verzeichnis wie die Datenbank befinden. Schlie&szlig;lich legt die Prozedur noch den Namen der Zieldatei fest, die unter <b>KategorienUndArtikel_Transformiert.xml <\/b>gespeichert werden soll. Die drei Variablen <b>strQuelle<\/b>, <b>strXSLT <\/b>und <b>strZiel <\/b>werden samt der Variablen <b>strFehler <\/b>f&uuml;r den optionalen Parameter an die Funktion <b>Transformieren <\/b>&uuml;bergeben. Sollte hier einer der oben erl&auml;uterten Fehler auftreten, liefert diese einen Wert ungleich <b>0 <\/b>zur&uuml;ck, was zur Ausgabe der mit <b>strFehler <\/b>zur&uuml;ckgegebenen Fehlermeldung per <b>MsgBox<\/b>-Anweisung f&uuml;hrt. Anderenfalls finden Sie nun in der Datei <b>KategorienUndArtikel_Transformiert.xml <\/b>das transformierte XML-Dokument vor. Sie k&ouml;nnen sich das Beispiel vorab anhand der Beispieldaten anschauen, in den folgenden Abschnitten erl&auml;utern wir die einzelnen Elemente einer <b>.xslt<\/b>-Datei.<\/p>\n<h2>XSLT<\/h2>\n<p><b>XSLT <\/b>ist die Sprache, mit der Transformationen von XML-Dateien in andere XML-Dateien oder auch HTML-Dateien durchgef&uuml;hrt werden. Dabei greifen Sie &uuml;ber eine spezielle weitere Sprache namens <b>XPath <\/b>auf das oder die gew&uuml;nschten Elemente des zu transformierenden XML-Dokuments zu und &uuml;berf&uuml;hren die kompletten Elemente oder auch nur deren Inhalt in das zu erstellende Dokument. Die Sprache XPath und ihre Anwendung mittels VBA beschreiben wir in einem weiteren Beitrag namens <b>VBA und XPath <\/b>(<b>www.access-im-unternehmen.de\/1050<\/b>).<\/p>\n<p>Wenn Sie schon einmal eine Webseite programmiert haben, die nicht nur aus reinem HTML besteht, sondern auch aus Skript-Elementen etwa auf Basis von PHP oder ASP\/ASP.NET, haben Sie unbewusst bereits eine Vorstellung davon, wie XSLT ein neues Dokument auf Basis eines bestehenden Dokuments zusammensetzt. Ein XSLT-Dokument ist dabei &auml;hnlich aufgebaut wie eine aus Skript- und HTML-Teilen bestehende Webseite.<\/p>\n<p>Sie finden dort n&auml;mlich feste Zeichenketten, aber auch dynamische Elemente, mit denen etwa die Inhalte des zu transformierenden Dokuments ermittelt und ausgegeben werden.<\/p>\n<h2>XSLT deklarieren<\/h2>\n<p>Damit die <b>.xslt<\/b>-Datei korrekt interpretiert werden kann, teilen wir der jeweiligen Verarbeitungsinstanz (in unserem Beispiel etwa die Methode <b>transformNodeToObject<\/b>) mit einer entsprechenden Deklaration in der ersten Zeile mit, um was f&uuml;r einen Dokumenttyp es sich handelt. In diesem Fall soll die Datei mit der folgenden Zeile starten:<\/p>\n<pre>&lt;xsl:stylesheet version=\"1.0\"\r\n   xmlns:xsl=\"http:\/\/www.w3.org\/1999\/XSL\/Transform\"\r\n   xmlns=\"http:\/\/www.w3.org\/TR\/REC-html40\"&gt;<\/pre>\n<p>Damit wird der offizielle Namespace des W3C-Konsortiums vorgegeben. Alle folgenden Zeilen, die XSLT-Befehle enthalten, starten mit <b>&lt;xsl:<\/b> und werden mit einem XSLT-Schl&uuml;sselwort fortgesetzt. Dadurch k&ouml;nnen Sie die auszuf&uuml;hrenden Elemente des <b>.xslt<\/b>-Dokuments von den statischen Elementen unterscheiden &#8211; &auml;hnlich wie etwa beim einem PHP-Dokument, wo die PHP-Anweisungen in <b><php ... ><\/b>-Bl&ouml;cken stehen.<\/p>\n<p>Dieser Zeile stellen wir noch die folgende Zeile voran:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-8\"&gt;<\/pre>\n<h2>Das template-Element<\/h2>\n<p>Das Basis-Element einer <b>.xslt<\/b>-Datei ist das <b>template<\/b>-Element. Es enth&auml;lt auch ein Attribut namens <b>match<\/b>. Mit <b>match<\/b> referenzieren Sie das Element eines XML-Dokuments, auf das sich die innerhalb des <b>template<\/b>-Elements befindlichen Elemente beziehen. Der Wert von <b>match <\/b>ist ein <b>XPath<\/b>-Ausdruck. XPath ist, wie oben bereits erw&auml;hnt wurde, die Sprache f&uuml;r den Zugriff auf die Elemente in einem XML-Dokument. Jede Menge Beispiele dazu finden Sie im Beitrag <b>VBA und XPath <\/b>(<b>www.access-im-unternehmen.de\/1050<\/b>). Wenn Sie beispielsweise auf das Root-Element des Dokuments (also das oberste Element) zugreifen wollen, geben Sie f&uuml;r das Attribut <b>match <\/b>einen Schr&auml;gstrich an (<b>\/<\/b>).<\/p>\n<p>Es werden nur Informationen ausgegeben, die sich innerhalb eines <b>template<\/b>-Elements befinden. Sie k&ouml;nnen also Folgendes in die <b>.xslt<\/b>-Datei schreiben und es wird nichts ausgegeben:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"utf-8\"&gt;\r\n&lt;xsl:stylesheet version=\"1.0\"\r\n     xmlns:xsl=\"http:\/\/www.w3.org\/1999\/XSL\/Transform\"\r\n     xmlns=\"http:\/\/www.w3.org\/TR\/REC-html40\"&gt;\r\n   &lt;blabla&gt;blub&lt;\/blabla&gt;\r\n   &lt;xsl:template match=\"\/\"&gt;\r\n   &lt;\/xsl:template&gt;\r\n&lt;\/xsl:stylesheet&gt;<\/pre>\n<p>Innerhalb des <b>template<\/b>-Elements befinden sich keine Daten, und das davor angegebene <b>blabla<\/b>-Element wird nicht ausgegeben, weil es sich nicht innerhalb eines <b>template<\/b>-Elements befindet. Das Ergebnisdokument ist folglich leer. Wenn Sie das <b>blabla<\/b>-Element innerhalb des <b>template<\/b>-Elements platzieren, wird es allerdings ausgegeben:<\/p>\n<pre>&lt;xsl:stylesheet version=\"1.0\" ...&gt;\r\n   &lt;xsl:template match=\"\/\"&gt;\r\n     &lt;blabla&gt;blub&lt;\/blabla&gt;\r\n   &lt;\/xsl:template&gt;\r\n&lt;\/xsl:stylesheet&gt;<\/pre>\n<p>Das hei&szlig;t, dass Sie selbst eigene Elemente zur Ausgabe hinzuf&uuml;gen k&ouml;nnen, auch ohne dynamische <b>xsl:&#8230;<\/b>-Elemente innerhalb des <b>template<\/b>-Elements hinzuzuf&uuml;gen. Sie k&ouml;nnten also etwa die Grundstruktur des Dokuments anlegen:<\/p>\n<pre>&lt;xsl:stylesheet version=\"1.0\" ...&gt;\r\n   &lt;xsl:template match=\"\/\"&gt;\r\n     &lt;Bestellverwaltung&gt;\r\n     &lt;\/Bestellverwaltung&gt;\r\n   &lt;\/xsl:template&gt;\r\n&lt;\/xsl:stylesheet&gt;<\/pre>\n<p><!--30percent--><\/p>\n<p>Dies liefert die folgende Ausgabe:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung ...&gt;&lt;\/Bestellverwaltung&gt;<\/pre>\n<h2>Zeilenumbruch herstellen<\/h2>\n<p>XML-Dokumente haben den Vorteil, dass sie sowohl maschinell erfasst werden k&ouml;nnen also auch durch das menschliche Auge in den meisten F&auml;llen gut verarbeitet werden k&ouml;nnen. Dies f&auml;llt jedoch umso leichter, wenn der Inhalt des Dokuments einigerma&szlig;en strukturiert ausgegeben wird &#8211; also mit Zeilenumbr&uuml;chen und Einr&uuml;ckungen. Das vorherige Beispiel enth&auml;lt keine Zeilenumbr&uuml;che, was bei dem Hauptelement <b><Bestellverwaltung> <\/b>jedoch hilfreich w&auml;re, da ja dazwischen noch einige weitere Informationen eingef&uuml;gt werden sollen. Also f&uuml;gen wir dazwischen einen Zeilenumbruch hinzu, was wir mit dem Element <b><xsl:text>&#xa;<\/xsl:text> <\/b>erledigen:<\/p>\n<pre>&lt;xsl:stylesheet version=\"1.0\" ...&gt;\r\n   &lt;xsl:template match=\"\/\"&gt;\r\n     &lt;Bestellverwaltung&gt;\r\n         &lt;xsl:text&gt;&#xa;&lt;\/xsl:text&gt;\r\n     &lt;\/Bestellverwaltung&gt;\r\n   &lt;\/xsl:template&gt;\r\n&lt;\/xsl:stylesheet&gt;<\/pre>\n<p>Damit erhalten wir nun im Zieldokument:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung xmlns=\"http:\/\/www.w3.org\/TR\/REC-html40\"&gt;\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<p>Das ist viel besser &#8211; darauf k&ouml;nnen wir aufbauen! Das Element <b><xsl:text><\/b> schlie&szlig;t &uuml;brigens auszugebenden und zu interpretierenden Text ein. W&uuml;rden Sie den Ausdruck <b>&#xa; <\/b>genau wie etwa <b><Bestellverwaltung> <\/b>einfach in die <b>.xslt<\/b>-Datei schreiben, w&uuml;rde dies nicht korrekt als Zeilenumbruch interpretiert werden. Deshalb schlie&szlig;en Sie Platzhalter f&uuml;r ASCII-Zeichen wie <b>Chr(10)<\/b>, hier als <b>&#xa; <\/b>definiert (<b>a <\/b>ist hexadezimal und steht f&uuml;r <b>10<\/b>, <b>x <\/b>f&uuml;llt die zweistellige Hexadezimalzahl auf) in das <b><xsl:text><\/b>-Element ein.<\/p>\n<h2>Kommentare<\/h2>\n<p>Wenn Sie w&auml;hrend der Erstellung eines <b>.xslt<\/b>-Dokuments Bereiche auskommentieren wollen, finden Sie dazu ein eigenes Element. Dieses hei&szlig;t <b>comment <\/b>und wird beispielsweise wie folgt eingesetzt:<\/p>\n<pre>&lt;xsl:comment&gt;\r\n... auszukommentierender Bereich\r\n&lt;\/xsl:comment&gt;<\/pre>\n<h2>Daten aus dem Originaldokument ausgeben<\/h2>\n<p>Nun wollen wir endlich auf die Daten in unserem Ausgangsdokument zugreifen, das wir transformieren wollen. Bereits jetzt wird offensichtlich, dass es eher eine Neuerstellung eines Dokuments ist als eine Transformation, denn wir m&uuml;ssen wohl f&uuml;r jedes einzelne gew&uuml;nschte Element festlegen, ob und wo wir es platzieren wollen.<\/p>\n<p>Wenn Sie nur den Inhalt eines bestimmten Elements des Ausgangsdokuments ausgeben wollen, verwenden Sie dazu das <b>value-of<\/b>-Element. Dieses erwartet mit dem <b>select<\/b>-Attribut die Angabe des betroffenen Elements, das Sie wiederum mit einem XPath-Ausdruck definieren.<\/p>\n<p>Wir m&ouml;chten einfach den Namen der ersten Kategorie in unserem Ausgangsdokument ermitteln. Damit wir wissen, von welchem Aufbau wir beim Auslesen des Dokuments reden, haben wir dieses auszugsweise in Listing 3 abgebildet. Dieses Dokument wird mit der Prozedur <b>TestTransformieren <\/b>aus den beiden Tabellen <b>tblKategorien <\/b>und <b>tblArtikel <\/b>der Beispieldatenbank erzeugt, die wir weiter oben vorgestellt haben.<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-8\"&gt;\r\n&lt;dataroot xmlns:od=\"urn:schemas-microsoft-com:officedata\" generated=\"2016-07-09T10:30:28\"&gt;\r\n   &lt;tblKategorien&gt;\r\n     &lt;KategorieID&gt;1&lt;\/KategorieID&gt;\r\n     &lt;Kategoriename&gt;Getr&auml;nke&lt;\/Kategoriename&gt;\r\n     &lt;Beschreibung&gt;Alkoholfreie Getr&auml;nke, Kaffee, Tee, Bier&lt;\/Beschreibung&gt;\r\n     &lt;Abbildung&gt;...&lt;\/Abbildung&gt;\r\n     &lt;tblArtikel&gt;\r\n       &lt;ArtikelID&gt;1&lt;\/ArtikelID&gt;\r\n       &lt;Artikelname&gt;Chai&lt;\/Artikelname&gt;\r\n       &lt;LieferantID&gt;1&lt;\/LieferantID&gt;\r\n       &lt;KategorieID&gt;1&lt;\/KategorieID&gt;\r\n       &lt;Liefereinheit&gt;10 Kartons x 20 Beutel&lt;\/Liefereinheit&gt;\r\n       &lt;Einzelpreis&gt;9&lt;\/Einzelpreis&gt;\r\n       &lt;Lagerbestand&gt;39&lt;\/Lagerbestand&gt;\r\n       &lt;BestellteEinheiten&gt;0&lt;\/BestellteEinheiten&gt;\r\n       &lt;Mindestbestand&gt;10&lt;\/Mindestbestand&gt;\r\n       &lt;Auslaufartikel&gt;0&lt;\/Auslaufartikel&gt;\r\n     &lt;\/tblArtikel&gt;\r\n     &lt;tblArtikel&gt;\r\n       &lt;ArtikelID&gt;2&lt;\/ArtikelID&gt;\r\n       &lt;Artikelname&gt;Chang&lt;\/Artikelname&gt;\r\n       ...\r\n     &lt;\/tblArtikel&gt;\r\n     ...\r\n   &lt;\/tblKategorien&gt;\r\n   &lt;tblKategorien&gt;\r\n     &lt;KategorieID&gt;2&lt;\/KategorieID&gt;\r\n     &lt;Kategoriename&gt;Gew&uuml;rze&lt;\/Kategoriename&gt;\r\n     &lt;Beschreibung&gt;S&uuml;&szlig;e und saure So&szlig;en, Gew&uuml;rze&lt;\/Beschreibung&gt;\r\n     &lt;Abbildung&gt;...&lt;\/Abbildung&gt;\r\n     &lt;tblArtikel&gt;\r\n       &lt;ArtikelID&gt;3&lt;\/ArtikelID&gt;\r\n       &lt;Artikelname&gt;Aniseed Syrup&lt;\/Artikelname&gt;\r\n       ...\r\n     &lt;\/tblArtikel&gt;\r\n     ...\r\n   &lt;\/tblKategorien&gt;\r\n   ...\r\n&lt;\/dataroot&gt;<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Ausgangsdokument f&uuml;r unsere Experimente<\/span><\/b><\/p>\n<p>Wir m&ouml;chten also nun auf den Inhalt des Elements <b>Kategoriename <\/b>unterhalb von <b>dataroot <\/b>und <b>tblKategorien <\/b>zugreifen. Dazu f&uuml;gen wir unserem Dokument nun einfach eine Zeile mit dem <b>value-of<\/b>-Element und der Angabe des gesuchten Elements, also <b>dataroot\/tblKategorien\/Kategoriename<\/b> hinzu:<\/p>\n<pre>...\r\n&lt;Bestellverwaltung&gt;\r\n   &lt;xsl:text&gt;&#xa;&lt;\/xsl:text&gt;\r\n   &lt;xsl:value-of select=\"dataroot\/tblKategorien\/Kategoriename\"\/&gt;\r\n   &lt;xsl:text&gt;&#xa;&lt;\/xsl:text&gt;\r\n&lt;\/Bestellverwaltung&gt;\r\n...<\/pre>\n<p>Dies liefert nun ein XML-Dokument mit folgendem Inhalt:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung xmlns=\"http:\/\/www.w3.org\/TR\/REC-html40\"&gt;\r\nGetr&auml;nke\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<p>Oh &#8211; das ist zwar ein g&uuml;ltiges XML-Dokument, aber wir wollen die Kategorie nat&uuml;rlich in ein eigenes Element stecken.<\/p>\n<p>Dazu f&uuml;gen wir einfach ein paar statische Elemente zum <b>.xslt<\/b>-Dokument hinzu, sodass wir sowohl ein <b>Kategorie<\/b>&#8211; als auch ein <b>Kategoriename<\/b>-Element erhalten:<\/p>\n<pre>...\r\n&lt;xsl:template match=\"\/\"&gt;\r\n   &lt;Bestellverwaltung&gt;\r\n     &lt;xsl:text&gt;&#xa;&lt;\/xsl:text&gt;\r\n     &lt;Kategorie&gt;\r\n       &lt;xsl:text&gt;&#xa;&lt;\/xsl:text&gt;\r\n       &lt;Kategoriename&gt;\r\n         &lt;xsl:value-of  select=\"dataroot\/tblKategorien\/Kategoriename\"\/&gt;\r\n       &lt;\/Kategoriename&gt;\r\n       &lt;xsl:text&gt;&#xa;&lt;\/xsl:text&gt;\r\n     &lt;\/Kategorie&gt;\r\n     &lt;xsl:text&gt;&#xa;&lt;\/xsl:text&gt;\r\n   &lt;\/Bestellverwaltung&gt;\r\n&lt;\/xsl:template&gt;\r\n...<\/pre>\n<p>Innerhalb der <b>.xslt<\/b>-Datei haben wir &uuml;berall dort, wo Zeilenumbr&uuml;che eingef&uuml;gt werden sollen, das Element <b><xsl:text>&#xa;<\/xsl:text> <\/b>integriert. Einr&uuml;ckungen in Form von Leerzeichen oder Tab-Zeichen brauchen Sie &uuml;brigens nicht einzuf&uuml;gen, denn diese werden automatisch entsprechend der Struktur des XML-Dokuments erzeugt. Diese dienen also eher der &uuml;bersicht f&uuml;r das menschliche Auge.<\/p>\n<p>Das Ergebnis sieht schon eher nach XML aus:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung xmlns=\"http:\/\/www.w3.org\/TR\/REC-html40\"&gt;\r\n   &lt;Kategorie&gt;\r\n     &lt;Kategoriename&gt;Getr&auml;nke&lt;\/Kategoriename&gt;\r\n   &lt;\/Kategorie&gt;\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<h2>Attributwerte transformieren<\/h2>\n<p>Wenn das Ausgangsdokument Elemente mit Attributen enth&auml;lt, auf die Sie per XSLT zugreifen wollen, gelingt dies ebenfalls mit dem <b>value-of<\/b>-Element. Sie m&uuml;ssen hier nur den entsprechenden <b>select<\/b>-Ausdruck f&uuml;r ein Attribut verwenden. Auf die <b>ArtikelID <\/b>in <b><Artikel ArtikelID=\"1\"> <\/b>greifen Sie etwa mit einem Element wie dem folgenden zu:<\/p>\n<pre>&lt;xsl:value-of select=\"Artikel\/@ArtikelID\"&gt;<\/pre>\n<h2>Elemente per Schleife durchlaufen<\/h2>\n<p>Allerdings haben wir nun erst eine einzige Kategorie in das Zieldokument &uuml;bertragen. Wie gelangen wir an die &uuml;brigen<\/p>\n<p>Sie ahnen es bereits: Genau, wie es ein Element gibt, mit dem man auf das Ausgangselement zeigen kann (<b><xsl:template match=\"...\"><\/b>), und ein Element, mit dem Sie den Inhalt eines bestimmten Elements ermitteln k&ouml;nnen, liefert XSD auch ein Element, mit dem sich eine Schleife &auml;hnlich wie unter VBA abbilden l&auml;sst. Dieses Element entspricht der <b>For Each<\/b>-Schleife unter VBA und es durchl&auml;uft alle Elemente des angegebenen Namens, die sich im aktuellen Kontext befinden.<\/p>\n<p>Der folgende Ausschnitt zeigt, wie wir alle <b>tblKategorie<\/b>-Elemente unterhalb von <b>dataroot <\/b>durchlaufen. Dazu f&uuml;gen wir ein <b>for-each<\/b>-Element mit dem Bezug <b>dataroot\/tblKategorien <\/b>als XPath-Ausdruck an. Zwischen diesem und dem schlie&szlig;enden <b>for-each<\/b>-Element f&uuml;gen wir dann die Struktur ein, die wir f&uuml;r jede Kategorie im Zieldokument ausgeben wollen &#8211; n&auml;mlich das <b>Kategorie<\/b>-Element und darin das <b>Kategoriename<\/b>-Element mit dem Namen der Kategorie (die Zeilenumbruch-Ausdr&uuml;cke haben wir der &uuml;bersichtlichkeit halber weggelassen):<\/p>\n<pre>...\r\n&lt;xsl:template match=\"\/\"&gt;\r\n   &lt;Bestellverwaltung&gt;\r\n       &lt;xsl:for-each select=\"dataroot\/tblKategorien\"&gt;\r\n         &lt;Kategorie&gt;\r\n           &lt;Kategoriename&gt;\r\n             &lt;xsl:value-of select=\"Kategoriename\"\/&gt;\r\n           &lt;\/Kategoriename&gt;\r\n       &lt;\/Kategorie&gt;\r\n     &lt;\/xsl:for-each&gt;\r\n   &lt;\/Bestellverwaltung&gt;\r\n&lt;\/xsl:template&gt;\r\n...<\/pre>\n<p>Das Ergebnis sieht nun schon wesentlich besser aus:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung ...&gt;\r\n   &lt;Kategorie&gt;\r\n     &lt;Kategoriename&gt;Getr&auml;nke&lt;\/Kategoriename&gt;\r\n   &lt;\/Kategorie&gt;\r\n   &lt;Kategorie&gt;\r\n     &lt;Kategoriename&gt;Gew&uuml;rze&lt;\/Kategoriename&gt;\r\n   &lt;\/Kategorie&gt;\r\n...\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<p>Es erscheinen nun alle Kategorien inklusive Kategoriename in der Ausgabe.<\/p>\n<h2>Andere Elemente exportieren<\/h2>\n<p>Wir haben zwar ein Ausgangsdokument, das in der ersten Ebene Kategorien und darunter Artikel abbildet. Daraus haben wir nun die Kategorien extrahiert. Aber wer sagt eigentlich, dass wir nicht auch einfach die Artikel exportieren k&ouml;nnen, ohne auf die <b>tblKategorie<\/b>-Elemente R&uuml;cksicht zu nehmen Dazu formulieren wir einfach das Attribut <b>select <\/b>des <b>for-each<\/b>-Elements um, sodass es nach den <b>tblArtikel<\/b>-Elementen sucht &#8211; n&auml;mlich in <b>dataroot\/tblKategorien\/tblArtikel<\/b>. Au&szlig;erdem &auml;ndern wir nat&uuml;rlich die Bezeichnungen der zu erzeugenden Elemente und greifen mit dem <b>value-of<\/b>-Element nicht mehr auf <b>Kategoriename<\/b>, sondern auf <b>Artikelname <\/b>zu:<\/p>\n<pre>...\r\n&lt;Bestellverwaltung&gt;\r\n     &lt;xsl:for-each select=\"dataroot\/tblKategorien\/tblArtikel\"&gt;\r\n       &lt;Artikel&gt;\r\n         &lt;Artikelname&gt;\r\n           &lt;xsl:value-of select=\"Artikelname\"\/&gt;\r\n         &lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n   &lt;\/xsl:for-each&gt;\r\n&lt;\/Bestellverwaltung&gt;\r\n...<\/pre>\n<p>Das Ergebnis ist eine aus einer hierarchisch strukturierten XML-Datei mit zwei Ebenen exportierte XML-Datei, die nur noch die Elemente der zweiten Ebene enth&auml;lt:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung ...&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;Chai&lt;\/Artikelname&gt;\r\n   &lt;\/Artikel&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;Chang&lt;\/Artikelname&gt;\r\n   &lt;\/Artikel&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;Guaran\u00e1 Fant\u00e1stica&lt;\/Artikelname&gt;\r\n   &lt;\/Artikel&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;Sasquatch Ale&lt;\/Artikelname&gt;\r\n   &lt;\/Artikel&gt;\r\n   ...\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<p>Das Ergebnis sieht schon gut aus, aber was ist, wenn wir die Daten nach dem Artikelnamen sortiert ausgeben wollen<\/p>\n<h2>Sortierung nach Elementinhalten<\/h2>\n<p>Auch die Sortierung innerhalb einer <b>for-each<\/b>-Schleife ist kein Problem. Daf&uuml;r hinterlegen Sie einfach hinter dem &ouml;ffnenden <b>for-each<\/b>-Element ein <b>sort<\/b>-Element. Dieses verwendet ebenfalls das Attribut <b>select<\/b>, diesmal allerdings mit dem Elementnamen des Originaldokuments, nach dessen Inhalt das transformierte Dokument sortiert werden soll.<\/p>\n<p>Wichtig ist, dass das <b>sort<\/b>-Element direkt wieder geschlossen wird, nicht also etwa erst mit einem schlie&szlig;enden Element vor dem schlie&szlig;enden Element des <b>for-each<\/b>-Elements:<\/p>\n<pre>...\r\n&lt;xsl:for-each select=\"dataroot\/tblKategorien\/tblArtikel\"&gt;\r\n   &lt;xsl:sort select=\"Artikelname\"\/&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;\r\n       &lt;xsl:value-of select=\"Artikelname\"\/&gt;\r\n     &lt;\/Artikelname&gt;\r\n   &lt;\/Artikel&gt;\r\n&lt;\/xsl:for-each&gt;\r\n...<\/pre>\n<p>Die <b>Artikel<\/b>-Elemente kommen nun nach dem <b>Artikelnamen <\/b>sortiert im Zieldokument an:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung ...&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;Alice Mutton&lt;\/Artikelname&gt;\r\n   &lt;\/Artikel&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;Aniseed Syrup&lt;\/Artikelname&gt;\r\n   &lt;\/Artikel&gt;\r\n   ...\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<h2>Filtern nach Elementinhalten in for-each<\/h2>\n<p>Innerhalb der <b>for-each<\/b>-Anweisung k&ouml;nnen Sie auch daf&uuml;r sorgen, dass nur bestimmte Elemente ausgegeben werden. Dies legen Sie in der Definition des <b>select<\/b>-Attributs des <b>for-each<\/b>-Elements fest. Wenn Sie beispielsweise nur das Element mit dem Artikelnamen <b>Chai <\/b>ausgeben m&ouml;chten, definieren Sie den <b>select<\/b>-Wert des <b>for-each<\/b>-Elements wie folgt:<\/p>\n<pre>&lt;xsl:for-each select=\"dataroot\/tblKategorien\/ tblArtikel[Artikelname=''Chai']\"&gt;\r\n   ...\r\n&lt;\/xsl:for-each&gt;<\/pre>\n<p>Sie legen also das Kriterium in eckigen Klammern fest. Das Ergebnis sieht wie gew&uuml;nscht aus:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung ...&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;Chai&lt;\/Artikelname&gt;\r\n   &lt;\/Artikel&gt;\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<p>Nun wollen wir alle Artikel ausgeben, die mit dem Buchstaben <b>C <\/b>beginnen. Unsere Access-SQL-Vorkenntnisse verf&uuml;hren uns zu folgendem Ansatz mit dem Vergleichswert <b>C*<\/b>:<\/p>\n<pre>&lt;xsl:for-each select=\"dataroot\/tblKategorien\/ tblArtikel[Artikelname=''C*']\"&gt;\r\n   ...\r\n&lt;\/xsl:for-each&gt;<\/pre>\n<p>Dies fruchtet allerdings nicht &#8211; wir erhalten ein Dokument ohne <b>Artikel<\/b>-Elemente:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung ...&gt;\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<p>Auch der Einsatz des Prozentzeichens (<b>%<\/b>) als Platzhalter bringt kein anderes Ergebnis. Der Grund ist, dass XPath schlicht ganz andere Ausdr&uuml;cke f&uuml;r solche F&auml;lle verwendet. In diesem Fall handelt es sich um eine Art Funktion und der Ausdruck in eckigen Klammern hei&szlig;t <b>starts-with(Artikelname, &#8220;C&#8220;)<\/b>:<\/p>\n<pre>&lt;xsl:for-each select=\"dataroot\/tblKategorien\/tblArtikel[starts-with(Artikelname,''C'')]\"&gt;<\/pre>\n<p>Damit erhalten wir nun eine Liste wie zuvor, allerdings mit allen Artikeln, deren Artikelname mit dem Buchstaben <b>C <\/b>beginnt. Weitere M&ouml;glichkeiten hierzu finden Sie im Beitrag <b>VBA und XPath <\/b>(<b>www.access-im-unternehmen.de\/1050<\/b>).<\/p>\n<h2>Alternative Variante zum Filtern: if<\/h2>\n<p>Es gibt noch eine Alternative zum vorherigen Aussortieren der nicht gew&uuml;nschten Elemente. Dabei fassen Sie die auszugebenden Elemente, die in Abh&auml;ngigkeit von einer bestimmten Bedingung ausgegeben werden sollen, in das Element <b>if <\/b>ein.<\/p>\n<p>Das <b>if<\/b>-Element verwendet ein Attribut namens <b>test<\/b>, mit dem Sie den Ausdruck festlegen, nach dem entschieden werden soll, ob die eingeschlossenen Elemente ausgegeben werden sollen oder nicht. F&uuml;r einen ersten Versuch nutzen wir wieder das Kriterium <b>Artikelname=&#8220;Chai&#8220;<\/b>:<\/p>\n<pre>&lt;xsl:for-each select=\"dataroot\/tblKategorien\/tblArtikel\"&gt;\r\n   &lt;xsl:if test=\"Artikelname=''Chai''\"&gt;\r\n     &lt;Artikel&gt;\r\n       &lt;Artikelname&gt;\r\n         &lt;xsl:value-of select=\"Artikelname\"\/&gt;\r\n       &lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n   &lt;\/xsl:if&gt;\r\n&lt;\/xsl:for-each&gt;<\/pre>\n<p>Dies liefert auch die erwartete Ausgabe.<\/p>\n<p>Nun hoffen wir, dass wir hier die von SQL gewohnten Vergleichsausdr&uuml;cke nutzen k&ouml;nnen, und verwenden etwa einen Ausdruck wie <b>Artikelname=&#8220;C*&#8220;<\/b> oder alternativ <b>Artikelname=&#8220;C%&#8220;<\/b>. Dies gelingt allerdings auch im <b>if<\/b>-Element nicht.<\/p>\n<p>Stattdessen m&uuml;ssen wir auch hier eine Funktion nutzen &#8211; in diesem Fall zur Ausgabe aller <b>tblArtikel<\/b>-Elemente, deren Element <b>Artikelname <\/b>mit dem Buchstaben <b>C <\/b>beginnt:<\/p>\n<pre>&lt;xsl:for-each select=\"dataroot\/tblKategorien\/tblArtikel\"&gt;\r\n   &lt;xsl:if test=\"starts-with(Artikelname,''C'')\"&gt;\r\n     &lt;Artikel&gt;\r\n       &lt;Artikelname&gt;\r\n         &lt;xsl:value-of select=\"Artikelname\"\/&gt;\r\n       &lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n   &lt;\/xsl:if&gt;\r\n&lt;\/xsl:for-each&gt;<\/pre>\n<h2>Ersatz f&uuml;r If&#8230;Then: choose-when-otherwise<\/h2>\n<p>Mit dem hier gezeigten <b>if<\/b>-Element k&ouml;nnen Sie zwar eine Bedingung pr&uuml;fen, aber nicht festlegen, was getan werden soll, wenn diese Bedingung nicht eintritt (au&szlig;er, dass der Inhalt des &ouml;ffnenden und schlie&szlig;enden <b>if<\/b>-Elements nicht ausgegeben wird). Daher finden Sie unter XSLT auch ein Konstrukt, mit dem Sie <b>If&#8230;Else&#8230;Then<\/b>-Bedingungen abbilden k&ouml;nnen, aber auch <b>If&#8230;ElseIf&#8230;Else&#8230;Then<\/b>&#8211; oder <b>If&#8230;ElseIf<\/b>-Bedingungen, wobei immer mehrere <b>ElseIf<\/b>-Zweige m&ouml;glich sind.<\/p>\n<p>Der grunds&auml;tzliche Aufbau sieht wie folgt aus (immer innerhalb einer <b>for-each<\/b>-Struktur zu verwenden):<\/p>\n<pre>&lt;xsl:choose&gt;\r\n   &lt;xsl:when test=\"&lt;Bedingung&gt;\"&gt;\r\n     ...\r\n   &lt;\/xsl:when&gt;\r\n   ... weitere when-Elemente\r\n   &lt;xsl:otherwise&gt;\r\n   ...\r\n   &lt;\/xsl:otherwise&gt;\r\n&lt;\/xsl:choose&gt;<\/pre>\n<p>Die in den <b>when<\/b>-Elementen formulierten Bedingungen und das <b>otherwise<\/b>-Element werden immer in ein <b>choose<\/b>-Element eingefasst. Sie k&ouml;nnen mehr als eine <b>when<\/b>-Bedingung angeben. Das <b>otherwise<\/b>-Element darf nur einmal auftreten, kann aber auch weggelassen werden. Das folgende Beispiel sorgt daf&uuml;r, dass je nach dem Einzelpreis f&uuml;r einen Artikel das Element <b>Preisbereich <\/b>mit den Werten <b>G&uuml;nstig<\/b>, <b>Mittel <\/b>und <b>Teuer <\/b>zur Ausgabe des jeweiligen <b>Artikel<\/b>-Elements hinzugef&uuml;gt wird:<\/p>\n<pre>&lt;xsl:for-each select=\"dataroot\/tblKategorien\/tblArtikel\"&gt;\r\n   &lt;xsl:sort select=\"Artikelname\"\/&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;\r\n       &lt;xsl:value-of select=\"Artikelname\"\/&gt;\r\n     &lt;\/Artikelname&gt;\r\n     &lt;Einzelpreis&gt;\r\n       &lt;xsl:value-of select=\"Einzelpreis\"\/&gt;\r\n     &lt;\/Einzelpreis&gt;\r\n     &lt;xsl:choose&gt;\r\n       &lt;xsl:when test=\"Einzelpreis &lt; 10\"&gt;\r\n         &lt;Preisbereich&gt;G&uuml;nstig&lt;\/Preisbereich&gt;\r\n       &lt;\/xsl:when&gt;\r\n       &lt;xsl:when test=\"Einzelpreis &lt; 20\"&gt;\r\n         &lt;Preisbereich&gt;Mittel&lt;\/Preisbereich&gt;\r\n       &lt;\/xsl:when&gt;\r\n       &lt;xsl:otherwise&gt;\r\n         &lt;Preisbereich&gt;Teuer&lt;\/Preisbereich&gt;\r\n       &lt;\/xsl:otherwise&gt;\r\n     &lt;\/xsl:choose&gt;\r\n   &lt;\/Artikel&gt;\r\n&lt;\/xsl:for-each&gt;<\/pre>\n<p>Der Vergleichsoperator muss dabei maskiert werden, wenn er Zeichen enth&auml;lt, die auch in der Strukturierung von XML-Dokumenten zum Einsatz kommen &#8211; also etwa das Gr&ouml;&szlig;er- und das Kleiner-Zeichen. Das Gr&ouml;&szlig;er-Zeichen wird mit <b>&lt; <\/b>ersetzt, das Kleiner-Zeichen mit <b>&gt;<\/b>.<\/p>\n<p>Das Ergebnis sieht wie erwartet aus:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung ...&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;Alice Mutton&lt;\/Artikelname&gt;\r\n     &lt;Einzelpreis&gt;19.5&lt;\/Einzelpreis&gt;\r\n     &lt;Preisbereich&gt;Mittel&lt;\/Preisbereich&gt;\r\n   &lt;\/Artikel&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;Aniseed Syrup&lt;\/Artikelname&gt;\r\n     &lt;Einzelpreis&gt;5&lt;\/Einzelpreis&gt;\r\n     &lt;Preisbereich&gt;G&uuml;nstig&lt;\/Preisbereich&gt;\r\n   &lt;\/Artikel&gt;\r\n   &lt;Artikel&gt;\r\n     &lt;Artikelname&gt;Carnarvon Tigers&lt;\/Artikelname&gt;\r\n     &lt;Einzelpreis&gt;31.25&lt;\/Einzelpreis&gt;\r\n     &lt;Preisbereich&gt;Teuer&lt;\/Preisbereich&gt;\r\n   &lt;\/Artikel&gt;\r\n   ..\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<h2>Verschachtelte for-each-Schleife<\/h2>\n<p>F&uuml;r unseren Anwendungsfall, wo wir es mit <b>tblKategorie<\/b>-Elementen und untergeordneten <b>tblArtikel<\/b>-Elementen zu tun haben, ben&ouml;tigen wir verschachtelte <b>for-each<\/b>-Schleifen, um die beiden Hierarchie-Ebenen abzudecken und in das Zielformular zu &uuml;bertragen.<\/p>\n<p>Also verschachteln wir einfach zwei <b>for-each<\/b>-Schleifen-Elemente ineinander. Das &auml;u&szlig;ere soll sich wie im Beispiel von weiter oben, wo wir bereits einmal die <b>tblKategorie<\/b>-Elemente durchlaufen haben, &uuml;ber das <b>select<\/b>-Attribut mit dem Wert <b>dataroot\/tblKategorien <\/b>auf die <b>tblKategorie<\/b>-Elemente st&uuml;rzen. Nach der Ausgabe des <b>Kategorie<\/b>-Elements und des untergeordneten <b>Kategoriename<\/b>-Elements mit dem Kategorienamen als Inhalt folgt die innere <b>for-each<\/b>-Schleife. Da wir uns durch das &auml;u&szlig;ere <b>for-each<\/b>-Element bereits im Kontext des Elements <b>dataroot\/tblKategorien <\/b>befinden, brauchen wir hier mit dem <b>select<\/b>-Attribut nur noch das untergeordnete Element <b>tblArtikel <\/b>zu referenzieren und auf die enthaltenen Daten zuzugreifen:<\/p>\n<pre>&lt;xsl:template match=\"\/\"&gt;\r\n   &lt;Bestellverwaltung&gt;\r\n     &lt;xsl:for-each select=\"dataroot\/tblKategorien\"&gt;\r\n       &lt;Kategorie&gt;\r\n         &lt;Kategoriename&gt;\r\n           &lt;xsl:value-of select=\"Kategoriename\"\/&gt;\r\n         &lt;\/Kategoriename&gt;\r\n         &lt;xsl:for-each select=\"tblArtikel\"&gt;\r\n         &lt;Artikel&gt;\r\n           &lt;Artikelname&gt;\r\n             &lt;xsl:value-of select=\"Artikelname\"\/&gt;\r\n           &lt;\/Artikelname&gt;\r\n         &lt;\/Artikel&gt;\r\n         &lt;\/xsl:for-each&gt;\r\n       &lt;\/Kategorie&gt;\r\n     &lt;\/xsl:for-each&gt;\r\n   &lt;\/Bestellverwaltung&gt;\r\n&lt;\/xsl:template&gt;<\/pre>\n<p>Hier ein Auszug des Ergebnisses:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung ...&gt;\r\n   &lt;Kategorie&gt;\r\n     &lt;Kategoriename&gt;Getr&auml;nke&lt;\/Kategoriename&gt;\r\n     &lt;Artikel&gt;\r\n       &lt;Artikelname&gt;Chai&lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n     &lt;Artikel&gt;\r\n       &lt;Artikelname&gt;Chang&lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n     ...\r\n   &lt;\/Kategorie&gt;\r\n   &lt;Kategorie&gt;\r\n     &lt;Kategoriename&gt;Gew&uuml;rze&lt;\/Kategoriename&gt;\r\n     &lt;Artikel&gt;\r\n       &lt;Artikelname&gt;Aniseed Syrup&lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n     ...\r\n   &lt;\/Kategorie&gt;\r\n   ...\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<h2>Attribute hinzuf&uuml;gen<\/h2>\n<p>Nun m&ouml;chten wir, im Gegensatz zum Ausgangsdokument, wo die Prim&auml;rschl&uuml;sselwerte der Felder <b>KategorieID <\/b>und <b>ArtikelID <\/b>in eigenen Elementen landeten, Attribute f&uuml;r diese Werte zu den Elementen <b>Kategorie <\/b>und <b>Artikel <\/b>hinzuf&uuml;gen.<\/p>\n<p>Dies erledigen wir mit dem XSL-Element <b>attribute<\/b>, dem wir &uuml;ber das <b>name<\/b>-Attribut den gew&uuml;nschten Namen geben (also <b>KategorieID <\/b>und <b>ArtikelID<\/b>). Innerhalb des <b>attribut<\/b>-Elements stellen wir mit <b>&lt;xsl:value-of select=&#8220;&lt;Feldname&gt;&#8220;\/&gt; <\/b>den Wert des Attributs ein (ersetzen Sie <b>&lt;Feldname&gt; <\/b>durch den jeweiligen Feldnamen). Der relevante Ausschnitt hierf&uuml;r sieht so aus:<\/p>\n<pre>&lt;xsl:for-each select=\"dataroot\/tblKategorien\"&gt;\r\n   &lt;Kategorie&gt;\r\n     &lt;xsl:attribute name=\"KategorieID\"&gt;\r\n       &lt;xsl:value-of select=\"KategorieID\"\/&gt;\r\n     &lt;\/xsl:attribute&gt;\r\n     &lt;Kategoriename&gt;\r\n       &lt;xsl:value-of select=\"Kategoriename\"\/&gt;\r\n     &lt;\/Kategoriename&gt;\r\n     &lt;xsl:for-each select=\"tblArtikel\"&gt;\r\n       &lt;Artikel&gt;\r\n         &lt;xsl:attribute name=\"ArtikelID\"&gt;\r\n           &lt;xsl:value-of select=\"ArtikelID\"\/&gt;\r\n         &lt;\/xsl:attribute&gt;\r\n         &lt;Artikelname&gt;\r\n           &lt;xsl:value-of select=\"Artikelname\"\/&gt;\r\n         &lt;\/Artikelname&gt;\r\n       &lt;\/Artikel&gt;\r\n     &lt;\/xsl:for-each&gt;\r\n   &lt;\/Kategorie&gt;\r\n&lt;\/xsl:for-each&gt;<\/pre>\n<p>Im Ergebnis schl&auml;gt sich dies wie folgt nieder:<\/p>\n<pre>&lt;Bestellverwaltung ...&gt;\r\n   &lt;Kategorie KategorieID=\"1\"&gt;\r\n     &lt;Kategoriename&gt;Getr&auml;nke&lt;\/Kategoriename&gt;\r\n     &lt;Artikel ArtikelID=\"1\"&gt;\r\n       &lt;Artikelname&gt;Chai&lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n     &lt;Artikel ArtikelID=\"2\"&gt;\r\n       &lt;Artikelname&gt;Chang&lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n     ...\r\n   &lt;\/Kategorie&gt;\r\n   ...\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<h2>Untergeordnete Templates<\/h2>\n<p>Genau das gleiche Ergebnis wie mit dem vorherigen Code mit den beiden verschachtelten <b>for-each<\/b>-Elementen erhalten Sie auch mithilfe des Elements <b>apply-templates <\/b>in Zusammenarbeit mit weiteren <b>template<\/b>-Elementen.<\/p>\n<p>Wir teilen den Code der besseren &uuml;bersichtlichkeit einmal auf. Der erste Teil enth&auml;lt das &ouml;ffnende und schlie&szlig;ende <b>Bestellverwaltung<\/b>-Element sowie darin das Element <b><xsl:apply-templates><\/b>:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"utf-8\"&gt;\r\n&lt;xsl:stylesheet version=\"1.0\"\r\n   xmlns:xsl=\"http:\/\/www.w3.org\/1999\/XSL\/Transform\"\r\n   xmlns=\"http:\/\/www.w3.org\/TR\/REC-html40\"&gt;\r\n   &lt;xsl:template match=\"\/\"&gt;\r\n     &lt;Bestellverwaltung&gt;\r\n       &lt;xsl:apply-templates\/&gt;\r\n      &lt;\/Bestellverwaltung&gt;\r\n   &lt;\/xsl:template&gt;<\/pre>\n<p>Dieses <b>apply-templates<\/b>-Element durchsucht nun alle untergeordneten Elemente und gibt diese aus. Dabei handelt es sich um die Ebene mit den <b>tblKategorien<\/b>-Elementen. F&uuml;r diese legen wir wiederum ein <b>template<\/b>-Element fest, das wie folgt aussieht:<\/p>\n<pre>   &lt;xsl:template match=\"tblKategorien\"&gt;\r\n     &lt;Kategorie&gt;\r\n       &lt;xsl:attribute name=\"KategorieID\"&gt;\r\n         &lt;xsl:value-of select=\"KategorieID\"\/&gt;\r\n       &lt;\/xsl:attribute&gt;\r\n       &lt;Kategoriename&gt;\r\n         &lt;xsl:value-of select=\"Kategoriename\"\/&gt;\r\n       &lt;\/Kategoriename&gt;\r\n       &lt;xsl:apply-templates select=\"tblArtikel\"\/&gt;\r\n     &lt;\/Kategorie&gt;\r\n   &lt;\/xsl:template&gt;<\/pre>\n<p>Damit werden nun alle <b>tblKategorien<\/b>-Elemente durchlaufen (andere hat das <b>dataroot<\/b>-Element ja nicht) und entsprechend der Vorgaben im <b>template<\/b>-Element ausgegeben. Hier finden wir wiederum ein <b>apply-templates<\/b>-Element, das allerdings diesmal mit dem Attribut <b>select <\/b>genau angibt, welches untergeordnete Element referenziert werden soll, n&auml;mlich <b>tblArtikel<\/b>.<\/p>\n<p>Warum das Nun: Im Gegensatz zum Root-Element <b>dataroot <\/b>des Ausgangsdokuments hat das Element <b>tblKategorien <\/b>ja neben den <b>tblArtikel<\/b>-Elementen durchaus noch andere Kind-Elemente, n&auml;mlich <b>KategorieID<\/b>, <b>Kategoriename, Beschreibung <\/b>und <b>Abbildung<\/b>.<\/p>\n<p>W&uuml;rden wir hier nicht mit <b>select <\/b>auf <b>tblArtikel <\/b>verweisen, w&uuml;rden die Inhalte der &uuml;brigen untergeordneten Elemente auch ausgegeben.<\/p>\n<p>Das letzte <b>template<\/b>-Element bezieht sich auf die <b>tblArtikel<\/b>-Elemente. Sie sind genauso aufgebaut wie der Teil innerhalb des <b>for-each<\/b>-Elements aus den vorherigen Beispielen:<\/p>\n<pre>   &lt;xsl:template match=\"tblArtikel\"&gt;\r\n     &lt;Artikel&gt;\r\n       &lt;xsl:attribute name=\"ArtikelID\"&gt;\r\n         &lt;xsl:value-of select=\"ArtikelID\"\/&gt;\r\n       &lt;\/xsl:attribute&gt;\r\n       &lt;Artikelname&gt;\r\n         &lt;xsl:value-of select=\"Artikelname\"\/&gt;\r\n       &lt;\/Artikelname&gt;\r\n     &lt;\/Artikel&gt;\r\n   &lt;\/xsl:template&gt;\r\n&lt;\/xsl:stylesheet&gt;<\/pre>\n<p>W&uuml;rden wir das letzte <b>template<\/b>-Element aus der <b>.xslt<\/b>-Datei l&ouml;schen, dann w&uuml;rden die Werte der Elemente unterhalb von <b>tblArtikel <\/b>dennoch ausgegeben werden &#8211; allerdings ohne Ber&uuml;cksichtigung der Vorgaben aus dem <b>template<\/b>-Element.<\/p>\n<p>Dies s&auml;he dann etwas un&uuml;bersichtlich aus, da die Elemente fehlen:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung ...&gt;\r\n   &lt;Kategorie KategorieID=\"1\"&gt;\r\n     &lt;Kategoriename&gt;Getr&auml;nke&lt;\/Kategoriename&gt;\r\n1Chai1110 Kartons x 20 Beutel93901002Chang1124 x 12-oz-Flaschen9.5174025024\r\nGuaran\u00e1 Fant\u00e1stica10112 x 355-ml-Dosen2.252000134\r\nSasquatch Ale16124 x 12-oz-Flaschen7111015035\r\nSteeleye Stout16124 x 12-oz-Flaschen920015038\r\nC&ocirc;te de Blaye18112 x 75-cl-Flaschen131.7517015039\r\nChartreuse verte181750-ml-Flasche96905043\r\nIpoh Coffee20116 x 500-g-Dosen23171025067\r\nLaughing Lumberjack Lager16124 x 12-oz-Flaschen752010070\r\nOutback Lager7124 x 355-ml-Flaschen7.5151030075\r\nRh&ouml;nbr&auml;u Klosterbier12124 x 0,5-l-Flaschen3.875125025076\r\nLakkalik&ouml;&ouml;ri231500-ml-Flasche9570200&lt;\/Kategorie&gt;\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<h2>Formatierung anpassen<\/h2>\n<p>Der Export der Tabelle <b>tblArtikel <\/b>hat uns ein Element namens Einzelpreis beschert, das nur den reinen Zahlenwert enth&auml;lt, aber keinerlei Formatierung.<\/p>\n<p>Wenn Sie nun aber statt des Wertes <b>10 <\/b>den Ausdruck <b>EUR 10.00 <\/b>in Ihrem transformierten Dokument vorfinden wollen, m&uuml;ssen Sie dies in der <b>.xslt<\/b>-Datei festlegen:<\/p>\n<pre>&lt;Einzelpreis&gt;\r\n   &lt;xsl:value-of select=\"format-number(Einzelpreis, ''EUR #,##0.00'')\"\/&gt;\r\n&lt;\/Einzelpreis&gt;<\/pre>\n<p>Sie verwenden also die Funktion <b>format-number <\/b>als Wert des <b>select<\/b>-Attributs des <b>value-of<\/b>-Elements. Hier &uuml;bergeben Sie zwei Parameter: den Namen des auszulesenden Elements sowie den Format-Ausdruck. Das Ergebnis sieht dann so aus:<\/p>\n<pre>&lt;xml version=\"1.0\" encoding=\"UTF-16\"&gt;\r\n&lt;Bestellverwaltung ...&gt;\r\n   &lt;Kategorie KategorieID=\"1\"&gt;\r\n     &lt;Kategoriename&gt;Getr&auml;nke&lt;\/Kategoriename&gt;\r\n     &lt;Beschreibung&gt;Alkoholfreie Getr&auml;nke, ...&lt;\/Beschreibung&gt;\r\n     &lt;Artikel ArtikelID=\"1\"&gt;\r\n       &lt;Artikelname&gt;Chai&lt;\/Artikelname&gt;\r\n       &lt;Einzelpreis&gt;EUR 9.00&lt;\/Einzelpreis&gt;\r\n     &lt;\/Artikel&gt;\r\n     &lt;Artikel ArtikelID=\"2\"&gt;\r\n       &lt;Artikelname&gt;Chang&lt;\/Artikelname&gt;\r\n       &lt;Einzelpreis&gt;EUR 9.50&lt;\/Einzelpreis&gt;\r\n     &lt;\/Artikel&gt;\r\n     ...\r\n   &lt;\/Kategorie&gt;\r\n&lt;\/Bestellverwaltung&gt;<\/pre>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Mit <b>XSLT<\/b> und ein paar Zeilen VBA-Code k&ouml;nnen Sie zuvor mit der <b>ExportXML<\/b>-Methode exportierte Daten aus den Tabellen der Datenbank in das gew&uuml;nschte Format transformieren.<\/p>\n<p>In diesem Beitrag haben Sie die eine Funktion kennen gelernt, mit der Sie eine als Pfad angegebene XML-Datei mit einer ebenfalls als Pfad angegebenen <b>.xslt<\/b>-Datei transformieren und das Ergebnis wieder als XML-Dokument speichern k&ouml;nnen.<\/p>\n<p>Au&szlig;erdem haben Sie verschiedene XSLT-Elemente kennen gelernt, mit denen Sie die Transformation steuern k&ouml;nnen. Dazu geh&ouml;rt, dass Sie festlegen, welche Elemente der Ausgangsdatei im XML-Format &uuml;berhaupt ber&uuml;cksichtigt werden sollen. Au&szlig;erdem bestimmten Sie, wie die Elemente in der Zieldatei landen sollen. Dabei k&ouml;nnen Sie die Struktur beliebig anpassen.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>XSLT.zip<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{4CD72C4C-60BF-423A-8310-C785E6FB500C}\/aiu_1047.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mit den eingebauten Funktionen f&uuml;r den Export von Daten aus Tabellen und Abfragen in das XML-Format k&ouml;nnen Sie bereits recht gute Ergebnisse erzielen. Nat&uuml;rlich k&ouml;nnen Sie aber nicht komplett steuern, wie das Zieldokument sp&auml;ter aussehen wird. Je nach den Anforderungen der Anwendung, die das XML-Dokument weiterverarbeiten soll, sind noch &Auml;nderungen notwendig. Hier tritt die Transformation von XML-Dokumenten auf den Plan: Mit einer sogenannten .xslt-Datei legen Sie fest, wie ein Dokument in ein anderes umgeformt werden soll. Den vollst&auml;ndigen Vorgang steuern Sie dann per VBA-Prozedur. Dieser Beitrag liefert die Grundlagen der Transformation und die notwendigen VBA-Techniken.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662016,66042016,44000025],"tags":[],"class_list":["post-55001047","post","type-post","status-publish","format-standard","hentry","category-662016","category-66042016","category-VBA_und_Programmiertechniken"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>XML-Dokumente transformieren mit XSLT - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"XML-Dokumente transformieren mit XSLT\" \/>\n<meta property=\"og:description\" content=\"Mit den eingebauten Funktionen f&uuml;r den Export von Daten aus Tabellen und Abfragen in das XML-Format k&ouml;nnen Sie bereits recht gute Ergebnisse erzielen. Nat&uuml;rlich k&ouml;nnen Sie aber nicht komplett steuern, wie das Zieldokument sp&auml;ter aussehen wird. Je nach den Anforderungen der Anwendung, die das XML-Dokument weiterverarbeiten soll, sind noch &Auml;nderungen notwendig. Hier tritt die Transformation von XML-Dokumenten auf den Plan: Mit einer sogenannten .xslt-Datei legen Sie fest, wie ein Dokument in ein anderes umgeformt werden soll. Den vollst&auml;ndigen Vorgang steuern Sie dann per VBA-Prozedur. Dieser Beitrag liefert die Grundlagen der Transformation und die notwendigen VBA-Techniken.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T18:42:33+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg09.met.vgwort.de\/na\/638c857edf2b43e6ae49f4919dfbde07\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"31\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"XML-Dokumente transformieren mit XSLT\",\"datePublished\":\"2020-05-22T18:42:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/\"},\"wordCount\":3952,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/638c857edf2b43e6ae49f4919dfbde07\",\"articleSection\":[\"2016\",\"4\\\/2016\",\"VBA und Programmiertechniken\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/\",\"name\":\"XML-Dokumente transformieren mit XSLT - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/638c857edf2b43e6ae49f4919dfbde07\",\"datePublished\":\"2020-05-22T18:42:33+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/638c857edf2b43e6ae49f4919dfbde07\",\"contentUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/638c857edf2b43e6ae49f4919dfbde07\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/XMLDokumente_transformieren_mit_XSLT\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"XML-Dokumente transformieren mit XSLT\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"XML-Dokumente transformieren mit XSLT - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/","og_locale":"de_DE","og_type":"article","og_title":"XML-Dokumente transformieren mit XSLT","og_description":"Mit den eingebauten Funktionen f&uuml;r den Export von Daten aus Tabellen und Abfragen in das XML-Format k&ouml;nnen Sie bereits recht gute Ergebnisse erzielen. Nat&uuml;rlich k&ouml;nnen Sie aber nicht komplett steuern, wie das Zieldokument sp&auml;ter aussehen wird. Je nach den Anforderungen der Anwendung, die das XML-Dokument weiterverarbeiten soll, sind noch &Auml;nderungen notwendig. Hier tritt die Transformation von XML-Dokumenten auf den Plan: Mit einer sogenannten .xslt-Datei legen Sie fest, wie ein Dokument in ein anderes umgeformt werden soll. Den vollst&auml;ndigen Vorgang steuern Sie dann per VBA-Prozedur. Dieser Beitrag liefert die Grundlagen der Transformation und die notwendigen VBA-Techniken.","og_url":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T18:42:33+00:00","og_image":[{"url":"http:\/\/vg09.met.vgwort.de\/na\/638c857edf2b43e6ae49f4919dfbde07","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"31\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"XML-Dokumente transformieren mit XSLT","datePublished":"2020-05-22T18:42:33+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/"},"wordCount":3952,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/638c857edf2b43e6ae49f4919dfbde07","articleSection":["2016","4\/2016","VBA und Programmiertechniken"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/","url":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/","name":"XML-Dokumente transformieren mit XSLT - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/638c857edf2b43e6ae49f4919dfbde07","datePublished":"2020-05-22T18:42:33+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/#primaryimage","url":"http:\/\/vg09.met.vgwort.de\/na\/638c857edf2b43e6ae49f4919dfbde07","contentUrl":"http:\/\/vg09.met.vgwort.de\/na\/638c857edf2b43e6ae49f4919dfbde07"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/XMLDokumente_transformieren_mit_XSLT\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"XML-Dokumente transformieren mit XSLT"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001047","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55001047"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001047\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001047"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001047"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001047"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}