XSL / XSLT-Tipps / XSLT-Konvertierung von XML nach HTML / Einbindung externer XML-Dokumente
![]() |
![]() |
➪ Der Datenimport aus separaten XML-Dokumenten kann sinnvoll sein, um zusätzliche Informationen in den Konvertierungsprozess einzubinden, die im eigentlichen XML-Input-Dokument nicht vorhanden sind.
Schauen Sie sich zunächst die externen Daten an, die in den XSL-Transformationsprozess eingebunden werden sollen.
<Listen
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../xsd/Listen.xsd">
<Liste Listnr="1" Label="Flensburger Punkte">
<Wert Key="2">3</Wert>
<Wert Key="5">15</Wert>
<Wert Key="15">450</Wert>
<Default>0</Default>
</Liste>
</Listen>
Sinnvollerweise gibt es für ein solches Standard-Dokument ein XML-Schema, das eine klare Datenstruktur erzwingt, sodass die darauf aufbauende Konvertierungslogik unverändert bleiben kann.
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="Listen">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="Liste">
<xs:complexType>
<xs:sequence>
<xs:sequence maxOccurs="unbounded">
<xs:element name="Wert">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Key"
type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:choice>
<xs:element name="Default" type="xs:string"/>
<xs:element name="Error" type="xs:string"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="Label" type="xs:string"
use="optional"/>
<xs:attribute name="Listnr" type="xs:integer"
use="required"/>
<xs:attribute name="Listgruppe" type="xs:string"
use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Über die document-Funktion wird das externe XML-Dokument in eine Variable vlisten eingelesen. Diese Variable wird im Template listimport angesprochen, wobei noch zwei Parameter plistnr und pkey erwartet werden.
Nehmen Sie sich die Zeit, das folgende XPath-Statement eingehend zu studieren, denn es erklärt sehr viel über die interne Funktionsweise von XPath. Da hinter der Variablen vlisten, die hier als Variable über $vlisten abgesprochen werden muss, das gesamte externe Input-Dokument steht, kann über den Pfad des Root-Elements Listen und dessen Child-Elemente Liste eine komplexe Elementliste angesprochen werden. Um das richtige Liste-Element herauszufinden, wird dessen Attribut Listnr über @-Zeichen angesprochen und mit dem übergebenen Parameter plistnr (als Parameter mit $ ansprechbar) gleichgesetzt.
$vlisten/Listen/Liste[@Listnr = $plistnr]/Wert[@Key = $pkey]
Das Spiel wiederholt sich. In der gefundenen Liste kann es mehrere Child-Elemente Wert geben, Sie suchen jenen, dessen Key-Attribut mit einem Parameter pkey übereinstimmt.
Übergeben Sie dem Template listimport also die Parameter plistnr= "1" und pKey="15", so sucht das Template im eingebundenen externen XML-Dokument in der Liste mit @Listnr="1" jenen Wert, dessen Key 15 ist, findet als Ergebnis 450 und schreibt dieses Ergebnis in den Output-Stream.
Die restliche Logik dieses Templates listimport zielt darauf ab, zu prüfen, ob der betreffende Wert überhaupt vorhanden ist. Falls nicht, wird hier jener Wert ausgelesen, der im betreffenden "Default"-Element zugewiesen ist.
<xsl:variable name="vlisten"
select="document('file:///C:/wg/Listen.xml')" />
<xsl:template name="listimport">
<xsl:param name="plistnr" />
<xsl:param name="pkey" />
<xsl:choose>
<xsl:when
test="$vlisten/Listen/Liste[@Listnr = $plistnr]/Wert[@Key = $pkey]">
<xsl:value-of
select="$vlisten/Listen/Liste[@Listnr = $plistnr]/Wert[@Key = $pkey]" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select="$vlisten/Listen/Liste[@Listnr
= $plistnr]/Default" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Ausgehend von allen Elementen Mensch (in der xsl-for-each-Schleife angesprochen über den XPath-Ausdruck /Orte/Ort/Mensch) wurde nach dem Gehalt absteigend sortiert, Werte wie Gehalt und die sum(Kauf/Gesamt) wurden formatiert und nummeriert. Zusätzlich können gebräuchliche Techniken wie Cascading Stylesheets (<link href="print.css" rel="stylesheet" type="text/css"/>) sowie JavaScript zum Einsatz kommen.
In einer zusätzlichen Anweisung <tr onclick="alert('{vorname} {name} wohnt in {../name}');"/> kann definiert werden, dass eine MessageBox vom Browser aufgerufen wird, sobald Sie auf eine Zeile der Tabelle klicken. Weil die Ausgabe in einem HTML-Attribut erfolgen muss, kann der Inhalt der Datenquelle über die geschweiften Klammern {XPath-Ausdruck} eingebunden werden.
Die Dezimalformatierung erreichen Sie etwa über <xsl:value-of select="format-number(Gehalt, '#.##0,00', 'european')"/>; das setzt freilich die Top-Level-Deklaration des Dezimalformats voraus: <xsl:decimal-format name="european" decimal-separator="," grouping-separator="."/>. Innerhalb der for-each-Schleife absteigend sortieren können Sie über (<xsl:sort select="Gehalt" data-type="number" order="descending"/>).
wg / 26. Oktober 2020
Fragen? Anmerkungen? Tipps?
Bitte nehmen Sie Kontakt zu mir auf.
V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn
☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de