XSL-Übersicht / xsl:element

xsl:element

xsl:element

xsl:element erlaubt die flexible Generierung von XML-Elementen im Zieldokument. Der Vorteil gegenüber fixer Namensdefinition ist, dass der Elementname dynamisch generiert werden kann.

Auf dieser Seite:

In XSLT ist es einfach, XML-Elemente direkt zu generieren. So ergibt der Aufruf in XSLT 2.0


<xsl:template match="/">
  <wurzel>
    <stamm>
      <xsl:for-each select="1 to 3">
        <ast/>
      </xsl:for-each>        
    </stamm>
  </wurzel>
</xsl:template>

... oder alternativ:


<xsl:template match="/">
  <xsl:element name="wurzel">
    <xsl:element name="stamm">
      <xsl:for-each select="1 to 3">
        <xsl:element name="ast"/>
      </xsl:for-each> 
    </xsl:element>
  </xsl:element>  
</xsl:template>

... dieses Resultat:


<wurzel>
  <stamm>
   <ast/>
   <ast/>
   <ast/>
  </stamm>
</wurzel>

Das XML-Dokument mit xmlns:xsi und Attribut erzeugen

Auch die Einbindung von xmlns:xsi mit xsi:noNamespaceSchemaLocation stellt kein Problem dar:


<xsl:template match="/">
  <wurzel 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="irgendwoImWald.xsd">
    <stamm>
      <xsl:for-each select="1 to 3">
        <ast/>
      </xsl:for-each>        
    </stamm>
  </wurzel>
</xsl:template>

Geht es jedoch darum, den XML-Output samt Zuweisung eines XML-Schema-Dokuments via xsl:element zu erzeugen, ist es guter Stil, xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" in das Root-Element xsl:stylesheet zu verlagern: Anschliessend können Sie mit arbeiten.


<xsl:stylesheet 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     version="2.0">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <xsl:element name="wurzel">
      <xsl:attribute name="xsi:noNamespaceSchemaLocation">
           irgendwoImWald.xsd
      </xsl:attribute>
      <xsl:element name="stamm">
        <xsl:for-each select="1 to 3">
          <xsl:element name="ast"/>
        </xsl:for-each>
      </xsl:element>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

Das Ergebnis sieht in beiden Fällen so aus:


<wurzel 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="irgendwoImWald.xsd">
   <stamm>
      <ast/>
      <ast/>
      <ast/>
   </stamm>
</wurzel>

Konvertierung von Attributen in Elemente

Hilfreich sind auch die Features zur Generierung von oder zur XML-Schema-basierten Typkontrolle. Das sehen Sie unschwer bei der Konvertierung von Attributen in Elemente. Nehmen Sie das folgende XML-Input-Dokument, dessen einziges Element lediglich Attribute, aber keine Childnodes aufweist.


<Person nachname="Achim" 
        vorname="Achtlos" 
        Geburtsjahr="1970"/>

Gesucht wird nun ein Weg, sämtliche Attribute in eine Ziel-Struktur zu konvertieren, die ausschliesslich Elemente aufweist. Dies wird möglich mit einer Schleife über alle Attribute. Zur Laufzeit wird für jedes vorhandene Attribut ein neues Element generiert, das den Namen des Attributs sowie dessen Wert übernimmt.


<Mensch>
 <xsl:for-each select="/Person/attribute::*">
  <xsl:element name="{name()}">
   <xsl:value-of select="."/>
  </xsl:element>
 </xsl:for-each>
</Mensch>

Das Ergebnis ist:


<Mensch>
   <nachname>Achim</nachname>
   <vorname>Achtlos</vorname>
   <Geburtsjahr>1970</Geburtsjahr>
</Mensch>

Namespaces im XML-Input-Dokument

Soll dasselbe Ergebnis erreicht werden, wenn der XML-Input mit einem Namespace "belastet" ist, ...


<wg:Person 
    xmlns:wg="wilfried-grupe.de" 
    wg:nachname="Zenzi" 
    wg:vorname="Zwecklos" 
    wg:Geburtsjahr="1980"/>

so bietet sich die Arbeit mit und an:


<Mensch>
 <xsl:for-each 
      select="/*/child::*/attribute::*">  
  <xsl:element name="{local-name()}">
   <xsl:value-of select="."/>
  </xsl:element>
 </xsl:for-each>
</Mensch>

<Mensch>
   <nachname>Zenzi</nachname>
   <vorname>Zwecklos</vorname>
   <Geburtsjahr>1980</Geburtsjahr>
</Mensch>

Timestamp-Elemente

Ebenso ist es möglich, die Elementnamen mit einem Zeitstempel zu versehen (selten benötigt, aber doch verwendet). Für das folgende Beispiel benötige ich zwei Variablen, die die aktuelle Zeit ermitteln und zur weiteren Verwendung formatieren.


<xsl:variable name="vjetzt" 
     select="current-dateTime()"/> 
<xsl:variable name="vjetztf" 
     select="format-dateTime($vjetzt, 
        '[Y0001][M01][D1]','de','AD','DE')"/>

Diese Zeitstempel kommen nun bei der Generierung der Elementnamen zum Einsatz.


<xsl:element 
     name="element{$vjetztf}">
  <xsl:element name="wg:Tag{$vjetztf}" 
       namespace="http://www.wilfried-grupe.de">
     <xsl:value-of 
          select="day-from-dateTime($vjetzt)"/>
  </xsl:element>
  <xsl:element name="Monat{$vjetztf}">
     <xsl:value-of 
          select="month-from-dateTime($vjetzt)"/>
  </xsl:element>
  <xsl:element 
       name="Jahr{$vjetztf}" 
       namespace="http://www.wilfried-grupe.de" >
    <xsl:value-of 
         select="year-from-dateTime($vjetzt)"/>
  </xsl:element>
</xsl:element>

Interessant ist hier auch der Einsatz der XML-Schema-basierten Typkontrolle, die beim xsl:element name='Monat{$vjetztf}' sicherstellt, dass das Ergebnis eine positive Zahl sein muss.

Das Ergebnis lautet:


<element20180112>
  <wg:Tag20180112 
      xmlns:wg="http://www.wilfried-grupe.de">
      12
  </wg:Tag20180112>
  <Monat20180112>1</Monat20180112>
  <Jahr20180112
    xmlns="http://www.wilfried-grupe.de">
    2018
  </Jahr20180112>
</element20180112>

wg / 25. Juni 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_element.html