XSL-Übersicht / Konvertierung von XML nach XML / Arbeit mit temporären Bäumen

Arbeit mit temporären Bäumen

Arbeit mit temporären Bäumen

➪ Aufgabe: Stellen Sie alle Menschen in der Orte_hierarchisch.xml in Dreiergruppen dar, absteigend sortiert nach Gehalt und entsprechend nummeriert, so dass jeweils drei Menschen in einer Zeile stehen.

Diese Aufgabe kann gelöst werden durch die Arbeit mit Variablen, die als temporäre Bäume die Datenstruktur weitgehend abbilden. In einem zweiten Schritt ist es möglich, die Variablen abzuarbeiten, um zum Endergebnis zu kommen.

Betrachten Sie das folgende XML-Dokument:


<Orte>
  <Ort>
    <id>1</id>
    <name>Neustadt</name>
    <Mensch>
      <id>9</id>
      <name>Sprachlos</name>
      <vorname>Stefan</vorname>
      <Gehalt>5430</Gehalt>
      <idOrt>1</idOrt>
      <Kauf>...</Kauf>
    </Mensch>
  </Ort>
  <Ort>
    <id>2</id>
    <name>Darmstadt</name>
    <Mensch>...</Mensch>
  </Ort>
  <Ort>
    <id>3</id>
    <name>Kapstadt</name>
    <Mensch>
      <id>5</id>
      <name>Wasistlos</name>
      <vorname>Willi</vorname>
      <Gehalt>6789</Gehalt>
      <idOrt>3</idOrt>
      <Kauf>...</Kauf>
    </Mensch>
    <Mensch>
      <id>6</id>
      <name>Bodenlos</name>
      <vorname>Betty</vorname>
      <Gehalt>3450</Gehalt>
      <idOrt>3</idOrt>
      <Kauf>...</Kauf>
    </Mensch>
  </Ort>
</Orte>

Das XML-Dokument ist der Input für das folgende XSL-Stylesheet, das mit der Deklaration und Implementierung der Variablen valleLeute beginnt.


<xsl:stylesheet version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:fn="http://www.w3.org/2005/xpath-functions">
 <xsl:output method="html" indent="yes"/>
 <!-- Definition der Variablen als temporaerer Baum -->
 <xsl:variable name="valleLeute">
  <xsl:for-each select="/Orte/Ort/Mensch">
   <xsl:sort select="Gehalt" 
             data-type="number" 
             order="descending"/>
   <mensch pos="{position()}" 
           vn="{vorname}" 
           nn="{name}" 
           wo="{../name}" 
           eink="{Gehalt}"/>
  </xsl:for-each>
 </xsl:variable>

Damit erhält die Variable valleLeute eine völlig neue Struktur. Die Variable selber ist kein wohlgeformtes XML-Dokument, sondern eine Nodelist mit mehreren Elementen mensch, die jeweils die fünf Attribute pos, vn, nn, wo, eink aufweisen. pos enthält dabei die automatische Nummerierung nach vorheriger Sortierung durch xsl:sort select="Gehalt". Das urspünglich übermittelte Element id ist in diesem Zwischenschritt obsolet geworden.


<mensch pos="1" vn="Willi" nn="Wasistlos" 
        wo="Kapstadt" eink="6789"/>
<mensch pos="2" vn="Stefan" nn="Sprachlos" 
        wo="Neustadt" eink="5430"/>
<mensch pos="3" vn="Betty" nn="Bodenlos" 
        wo="Kapstadt" eink="3450"/>

Diese neue Struktur, die lediglich temporär im Arbeitsspeicher verfügbar ist, liefert wiederum den Input für eine Transformation in Dreiergruppen. Letztere werden dadurch gebildet, dass zunächst nur jedes dritte Element der Variablen valleLeute abgerufen und, von diesem ausgehend, das jeweils vorletzte, vorhergehende und aktuelle Element ausgewertet wird. Die Auswertung geschieht durch einen Loop über alle Attribute.


 <!-- Konvertierung der vorher definierten 
      Variablen in ein HTML-Dokument-->
 <xsl:template match="/">
  <html>
   <head>
    <title/>
   </head>
   <body>
    <table border="1">
     <tbody>
      <xsl:for-each select="$valleLeute/mensch[@pos mod 3=0]">
       <tr>
        <xsl:if test="fn:position() mod 2 = 1">
         <xsl:attribute name="bgcolor">lightgrey</xsl:attribute>
        </xsl:if>
        <td>
         <xsl:for-each select="./preceding::*[2]/attribute::*">
          <xsl:value-of select="."/>
          <xsl:if test="position() != last()">
           <xsl:element name="br"/>
          </xsl:if>
         </xsl:for-each>
        </td>
        <td>
         <xsl:for-each select="./preceding::*[1]/attribute::*">
          <xsl:value-of select="."/>
          <xsl:if test="position() != last()">
           <xsl:element name="br"/>
          </xsl:if>
         </xsl:for-each>
        </td>
        <td>
         <xsl:for-each select="./attribute::*">
          <xsl:value-of select="."/>
          <xsl:if test="position() != last()">
           <xsl:element name="br"/>
          </xsl:if>
         </xsl:for-each>
        </td>
       </tr>
      </xsl:for-each>
     </tbody>
    </table>
   </body>
  </html>
 </xsl:template>
</xsl:stylesheet>

Das Ergebnis der Transformation:


 <html>
  <head>
   <title/>
  </head>
  <body>
   <table border="1">
    <tbody>
     <tr bgcolor="lightgrey">
      <td>1<br/>Willi<br/>Wasistlos<br/>Kapstadt<br/>6789</td>
      <td>2<br/>Stefan<br/>Sprachlos<br/>Neustadt<br/>5430</td>
      <td>3<br/>Betty<br/>Bodenlos<br/>Kapstadt<br/>3450</td>
     </tr>
    </tbody>
   </table>
  </body>
 </html>

wg / 1. April 2018



Fragen? Anmerkungen? Tips?

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_XML2XML_3ergruppe.html