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 3er Gruppen dar, absteigend sortiert nach Gehalt und entsprechend numeriert, so daß jeweils drei Menschen in einer Zeile stehen.

Arbeit mit temporären Bäumen

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, diese Variable abzuarbeiten, um zum Endergebnis zu kommen.

Betrachten wir das folgende XML Dokument, das das uns bereits bestens bekannte Input-Dokument verkürzt darstellt.


<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 Variable "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 Variable 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 5 Attribute "pos", "vn", "nn", "wo", "eink" aufweisen. "pos" enthält dabei die automatische Numerierung 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, daß zunächst nur jedes dritte Element der Variable "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 
      Variable 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 / 7. November 2017



Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf:

Vorname
Nachname
Mailadresse







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: info2018@wilfried-grupe.de

www.wilfried-grupe.de/XSL_XML2XML_3ergruppe.html