XML | XML-Schema | XPath | XSL-T | XSL-FO | XQuery | XProc | SVG |
XSL-T / Die XSLT - Struktur / 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:Siehe
<xsl:element
name = { qualified name }
namespace = { URI }
use-attribute-sets = { qualified names }>
</xsl:element>
Siehe auch https://www.w3.org/TR/xslt-10/#element-element.
<xsl:element
name = { qname }
namespace? = { uri-reference }
inherit-namespaces? = "yes" | "no"
use-attribute-sets? = qnames
type? = qname
validation? = "strict" | "lax" | "preserve" | "strip">
<!-- Content: sequence-constructor -->
</xsl:element>
Siehe auch https://www.w3.org/TR/xslt20/#element-element.
Siehe auch https://www.w3.org/TR/xslt-30/#element-element.
In XSLT ist es einfach, XML-Elemente automatisch zu generieren. Hierfür steht xsl:element mit dem zwingend erforderlichen Attribut name zur Verfügung, das seit XSLT 1.0 bereit steht. Ein häufiger Anwendungsfall hierfür ist die Teilkonvertierrung über xsl:apply-templates.
name | Erforderlich, verfügbar seit XSLT 1.0. Hier muss ein qualified name stehen. Er kann auch einen Namespace-Präfix beinhalten. |
namespace | Optional, verfügbar seit XSLT 1.0. Hier kann ein Namensraum zugewiesen werden. Es kann mit oder ohne Namespace-Präfix deklariert werden. Hier ist ggf. auf unterschiedliche Outputs zu achten. |
inherit-namespaces | Optional, verfügbar seit XSLT 2.0. Es kann die Werte yes (Default) oder no beinhalten. Hier können Sie festlegen, ob die Namensraum-Knoten weitergegeben werden könnnen. |
type | Optional, verfügbar seit XSLT 2.0. Hier können Sie den Schema-Datentyp festlegen. Siehe nachfolgendes Beispiel. Das type-Attribut darf nicht zusammen mit dem validation-Attribut verwendet werden. |
validation | Optional, verfügbar seit XSLT 2.0. Das validation-Attribut darf nicht zusammen mit dem type-Attribut verwendet werden. Siehe auch xs:any, xs:anyType. |
use-attribute-sets | Optional, verfügbar seit XSLT 1.0. Siehe xsl:attribute-set. |
So ergibt der Aufruf in XSLT 2.0
<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>
... oder alternativ:
<xsl:template match="/">
<wurzel>
<stamm>
<xsl:for-each select="1 to 3">
<ast/>
</xsl:for-each>
</stamm>
</wurzel>
</xsl:template>
... dieses Resultat:
<wurzel>
<stamm>
<ast/>
<ast/>
<ast/>
</stamm>
</wurzel>
Die lokale Zuweisung eines Namensraums mithilfe des optionalen namespace-Attributes ...
<xsl:template match="/">
<xsl:element name="wurzel">
<xsl:element name="wg:stamm"
namespace="https://www.wilfried-grupe.de/XSL_element.html">
<xsl:for-each select="1 to 3">
<xsl:element name="ast"/>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:template>
... erzeugt dieses Resultat:
<wurzel>
<wg:stamm xmlns:wg="https://www.wilfried-grupe.de/XSL_element.html">
<ast/>
<ast/>
<ast/>
</wg:stamm>
</wurzel>
Das @type-Attribut erlaubt eine verbesserte Typkontrolle in Verbindung mit XML-Schema.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs" version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:element name="wurzel">
<xsl:element name="stamm">
<xsl:for-each select="1 to 3">
<xsl:element name="ast" type="xs:integer">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Siehe auch xsl:attribute-set.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs" version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:attribute-set name="as_Person">
<xsl:attribute name="nachname">Rielos</xsl:attribute>
<xsl:attribute name="vorname">Lotte</xsl:attribute>
</xsl:attribute-set>
<xsl:template match="/">
<xsl:element name="Mensch"
use-attribute-sets="as_Person">
</xsl:element>
</xsl:template>
</xsl:stylesheet>
zaubert dieses Ergebnis:
<Mensch nachname="Rielos" vorname="Lotte"/>
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 xsl:attribute 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>
Hilfreich sind auch die Features zur Generierung von Namespaces, Namespace-Prefixes 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>
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 child::* und local-name() 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>
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="https://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="https://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="https://www.wilfried-grupe.de">
12
</wg:Tag20180112>
<Monat20180112>1</Monat20180112>
<Jahr20180112
xmlns="https://www.wilfried-grupe.de">
2018
</Jahr20180112>
</element20180112>
wg / 17. April 2021
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