Gern stehe ich zur fachlichen Unterstützung in XML-Technologien, C#.NET, VisualBasic.NET und Java zur Verfügung. Sprechen Sie mich einfach an: Mail oder ☎ 0151 . 750 360 61


XSL-Übersicht / XSLT-Konvertierung von XML nach HTML / Einbindung externer XML-Dokumente

Einbindung externer XML-Dokumente

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.

pic/externeListen.png


<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 / 16. November 2018



Fragen? Anmerkungen? Tipps?

Bitte nehmen Sie Kontakt zu mir auf.






Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/XSL_XML2HTML2.html