xsl:copy

(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 6.)

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

 

Die Instruktion xsl:copy dient zum Kopieren eines Knotens in die der Serialisierung zugrunde liegende Ergebnissequenz (quasi also in das Ergebnisdokument). Es werden dabei (entsprechend einer »flachen« Kopie) für Elementknoten nicht automatisch deren Kind- oder Attributknoten mitkopiert – ihre Namensraumknoten hingegen schon.

Klassifizierung Instruktion
Funktionsgruppe Kopieren aus dem Quelldokument
Einführung XSLT 1.0

Position im Stylesheet und erlaubte Inhalte:

xsl:copy darf ausschließlich im Inneren von xsl:template-Elementen eingesetzt werden.

Die Instruktion ist in der Regel leer, kann aber auch einen Templatebody in Form eines Sequenzkonstruktors enthalten. Dieser tritt allerdings nur in Kraft, wenn ein Element- oder Dokumentknoten kopiert wird.

Attribute:

Für xsl:copy gelten die Standardattribute. Ansonsten besitzt die Instruktion ein optionales Attribut use-attribute-sets und – seit XSLT 2.0 – die ebenfalls optionalen Attribute copy-namespaces, inherit-namespaces, type und validation.

copy-namespaces

Wert

"yes” (Default) | "no”

Verwendung

Optional

Einführung

XSLT 2.0

Das Attribut copy-namespaces ist nur auf kopierte Elementknoten anwendbar. Mit den Werten yes oder no wird festgelegt, ob mit einem kopierten Elementknoten auch seine Namensraumknoten mitkopiert werden. Als Defaultwert bei Abwesenheit des Attributs gilt yes. Normalerweise werden die Namensraumknoten eines Elements also kopiert (und an eventuelle Kindknoten vererbt, die mittels des Sequenzkonstruktors im Inneren der xsl:copy-Instruktion erzeugt wurden – siehe hierzu das Attribut inherit-namespaces).

Hinweis: Das Attribut existiert nicht in XSLT 1.0.

inherit-namespaces

Wert

"yes" (Default) | "no"

Verwendung

Optional

Einführung

XSLT 2.0

Das Attribut inherit-namespaces ist nur auf kopierte Elementknoten anwendbar. Mit den Werten yes oder no wird festgelegt, ob mitkopierte Namensraumknoten an Kindknoten des kopierten Elementknotens, wie sie mittels des optionalen Sequenzkonstruktors im Inneren der Instruktion xsl:copy erzeugt werden können, vererbt werden, oder nicht. Als Defaultwert bei Abwesenheit des Attributs gilt yes. Normalerweise werden Namensraumknoten daher vererbt (allerdings darf hierfür deren Kopieren nicht unterbunden worden sein).

Hinweis: Das Attribut existiert nicht in XSLT 1.0.

type

Wert

QName

Verwendung

Optional (nicht gleichzeitig mit validation-Attribut)

Einführung

XSLT 2.0

Das type-Attribut nennt den QName eines Schema-Datentyps, der mit den kopierten Element- und Attributknoten verknüpft werden soll. Es kann sich um einen vordefinierten (built-in) Typ oder um einen Typ aus einem importierten Schema handeln. Es ist ein statischer Fehler, wenn keine Deklaration dieses Namens auffindbar ist (ERR XTSE1520). Ist die Validierung erfolgreich, d.h., hat das validity-Property des entsprechend erzeugten PSVI den Wert valid, so wird der genannte Datentyp mit dem Knoten verknüpft, andernfalls wird die Verarbeitung des Stylesheets abgebrochen (ERR XTTE1540).

Speziell für kopierte Attributknoten gilt im Besonderen, dass eine, ihnen zugewiesene existierende Typdefinition sich nicht auf einen komplexen Typ beziehen darf – da ein Attribut keinen komplexen Typ besitzen darf, gilt dies als statischer Fehler (ERR XTSE1530).

Hinweis: Das type-Attribut darf nicht gleichzeitig mit dem validation-Attribut verwendet werden. Das Attribut existiert nicht in XSLT 1.0.

use-attribute-sets

Wert

QNames

Verwendung

Optional

Einführung

XSLT 1.0

Das use-attribute-sets-Attribut bindet diejenigen Attributsets an das kopierte Element, deren Bezeichner einem der im Attributwert gelisteten qualifizierten Bezeichner (QNames) entspricht. Die übergebenen QNames werden durch Whitespacezeichen getrennt.

validation

Wert

"strict" | "lax" | "preserve" | "strip"

Verwendung

Optional (nicht gleichzeitig mit type-Attribut)

Einführung

XSLT 2.0

Das validation-Attribut bestimmt die Validierungsstufe. Der Default­wert bei Abwesenheit des Attributs ist strip, sofern nicht im xsl:styles­heet-Element ein default-validation-Attribut mit anderem Wert gesetzt ist. Handelt es sich bei dem zu kopierenden Item nicht um einen Element- oder Attributknoten, so wird das validation-Attribut ignoriert.

Hinweis: Das validation-Attribut darf nicht gleichzeitig mit dem type-Attribut verwendet werden. Das Attribut existiert nicht in XSLT 1.0.

Die vier möglichen expliziten Werte sind strict, lax, preserve und strip – sie haben im Falle von xsl:copy im Einzelnen folgende Wirkungen:

  • validation="strict"
    Der Wert strict erzwingt eine strikte Validierung des kopierten Knotens gemäß eines Schemas. Der Knoten muss also in einem Schema deklariert sein, das an dieser Stelle mit Hilfe der in XML Schema üblichen Methoden zur Verfügung stehen muss. Das so für den Kno­ten ermittelte validity-Property im Rahmen des entsprechenden PSVI muss den Wert valid besitzen. Hat das Property den Wert invalid oder notKnown, so scheitert die Transformation an dieser Stelle mit einem Typfehler (ERR XTTE1510 bzw. ERR XTTE1512).
  • validation="lax"
    Der Wert lax erfordert ebenfalls eine Validierung des kopierten Knotens gemäß eines zur Verfügung stehenden Schemas. Allerdings gilt es nicht als Fehler, wenn kein solches Schema zur Verfügung steht oder der Knoten im Rahmen eines vorhandenen Schemas nicht dekla­riert ist. Das für den Knoten ermittelte validity-Property darf also neben valid auch den Wert notKnown besitzen. In letzterem Fall wird dem (nicht validierten) Knoten der Typ xs:untyped zugewiesen, falls es sich um einen kopierten Elementknoten handelt. Der Typ eines kopierten Attribut­knotens bleibt im Gegensatz dazu unverändert. Hat das validity-Property dagegen den Wert invalid, so scheitert die Transformation an dieser Stelle wiederum mit einem Typfehler (ERR XTTE1515).
  • validation="preserve"
    Der Wert preserve erhält für einen kopierten Attributknoten dessen Bindung an den jeweiligen Datentyp. Ist der kopierte Knoten dagegen ein Elementknoten, so wird seine Typbindung aufgehoben und der Kopie statt dessen der allgemeine Typ xs:anyType zugewiesen. Dies geschieht auf Grund der Annahme, dass eventueller Elementinhalt nicht in jedem Fall mitkopiert werden wird, der Inhalt des Elements sich daher mög­licherweise ändert. Inhalte bewahren jedoch gegebenenfalls ihren Typ.
  • validation="strip"
    Der Wert strip unterbindet eine Schemavalidierung und löst jegliche eventuell vorhan­dene Datentypbindung. Einem kopierten Attributknoten wird der Typ xs:untypedAtomic und einem kopierten Elementknoten der Typ xs:untyped zugewiesen. Für letztere wird deren nilled-Property generell auf den Wert false gesetzt. Ein kopierter Attributknoten, bei dem es sich um einen Identifier ID oder ein IDREFS-Attribut handelt, behält seine is-id- bzw. seine is-idrefs-Eigenschaft.

Verwendungszweck:

Die Anweisung xsl:copy kopiert das aktuelle Item und fügt dieses in die Ergebnissequenz ein, aus der im Zuge der Seriali­sierung das Ergebnisdokument der Transformation gebildet wird. Die Instruk­tion kann auf alle Knotentypen sowie auf atomare Werte angewendet werden.

Steht ein atomarer Wert zum Kopieren an, so wird er unverändert in die Ergeb­nissequenz kopiert. Falls es sich um einen Node handelt, werden dessen Kind­knoten (sofern vorhanden) nicht automatisch berücksichtigt (soll dies gesche­hen, so kann man alternativ xsl:copy-of einsetzen).

Der optionale Inhalt der Anweisung xsl:copy dient zur Erzeugung von Kind­knoten eines kopierten Knotens, hat also die Form eines Sequenzkonstruk­tors (sequence constructor). Er kann allerdings nur auf diejenigen kopierten Knoten angewendet werden, deren Typ das Auftreten von Inhalten (Kindkno­ten) auch zulässt, also auf Element- oder Dokumentknoten. Werden bei Aus­wertung der Instruktion Namensraumknoten mitkopiert oder Attributsets angewendet, so erscheinen die entsprechenden Knoten in der Ergebnissequenz stets vor eventuellen, durch den Sequenzkonstruktor erzeugten Knoten.

Oft wird man in diesem Anweisungsblock daher die Instruktion xsl:apply-templates vorfinden, die benötigt wird, um beispielsweise Kindknoten eines aktuell kopierten Elementknotens weiterverarbeiten zu können. Lässt das kopierte Item das Anfügen von Inhalten nicht zu (wie bei atomaren Werten, Attribut-, Text- oder Kommentarknoten), wird der in der Instruktion enthal­tene Anweisungsblock ignoriert (es tritt also kein Fehler auf).

Mit kopierten Element- oder Attributknoten verknüpfte Namensraumknoten werden automatisch mitkopiert (sofern das copy-namespaces-Attribut, siehe unten, nicht anderes aussagt). Wird mittels xsl:copy ein Element im Null-Namensraum als Inhalt an ein anderes Element angefügt, so wird umgekehrt ein nicht leerer Default-Namensraum des Elternknotens nicht automatisch auf das kopierte Ele­ment übertragen. Gegebenenfalls wird im Zuge der Serialisierung eine Namensraum-Undeklaration mittels xmlns="" am kopierten Element vorge­nommen.

Anwendung von xsl:copy auf Elementknoten:
Im Ergebnisdokument wird bei der Serialisierung eine Kopie des Elements mitsamt Namensraumknoten erzeugt. Falls ein Sequenzkonstruktor in xsl:copy vorhanden ist, wird er aus­geführt und seine Ausgabesequenz in Form von entsprechenden Kindknoten an den kopierten Elementknoten angehängt. Die Kindknoten »erben« zusammen mit dem Elternknoten kopierte Namensräume, sofern nicht das inherit-namespaces-Attribut auf den Wert no gesetzt wird.

Besitzt xsl:copy ein use-attribute-sets-Attribut, so werden die dort bezeichneten Attributsets auf das kopierte Element angewendet. Liegt ein type- oder validation-Attribut vor, so wird der kopierte Elementknoten ent­sprechend dessen Anweisungen geprüft.

Ab XSLT 2.0 ist es möglich, das automatische Kopieren des Namensraums durch Setzen des neu hinzugekommenen Attributs copy-namespaces auf no zu unterbinden. Im Inneren der Instruktion könnte in Folge mittels der Instruktion xsl:namespace ein neuer Namensraum an das kopierte Element gebunden werden (dies ist auch für einen im Ergebnisdokument gültigen Default-Namensraum erforderlich).

Anwendung von xsl:copy auf Dokumentknoten:
xsl:copy kann auch auf einen Dokumentknoten, z.B. auf einen temporären Baum einer Variable, ange­wendet werden. Dabei wird der Dokumentknoten des Baums selbst jedoch nicht der primären Ergebnis­sequenz hinzugefügt, sondern lediglich seine Inhalte. Ein potenzieller Sequenzkon­struktor im Inneren von xsl:copy wird also ausgeführt, da ein Dokumentknoten in diesem Zusammenhang als ein normaler Elementknoten betrachtet wird.

Ein kopierter Dokumentknoten wird entsprechend eines vorhandenen type- oder validation-Attributs geprüft: Die Validierung eines aus einer Variable stammenden, bereits existierenden, temporären Baums ist somit im Zuge des Kopiervorgangs möglich. (Eine vorhergehende Validierung eines temporären Baums während seiner Erzeugung kann nicht vorgenommen werden, da  xsl:variable die dafür erforderlichen Attribute nicht besitzt. In Verbindung mit der Instruktion xsl:document wäre eine Validierung eines erstellten Baums allerdings möglich.)

Ein in xsl:copy verwendetes use-attribut-sets-Attribut wird im Zusam­menhang mit Dokumentknoten ignoriert (da ein Dokumentknoten keine Attri­bute besitzen kann).

Anwendung von xsl:copy auf Attributknoten:
Wird xsl:copy auf Attribut­knoten angewendet, so wird das Attribut und sein Wert kopiert, ein eventuell vorhandener Namensraum wird während des Namespace-Fixup-Prozesses berücksichtigt. Bei Serialisierung der Ergebnissequenz muss zum Zeitpunkt der Verarbeitung des kopierten Attributknotens ein Ziel­element offen sein, wel­ches das Attribut aufnehmen kann. Besitzt dieses Ziel­element bereits ein gleich­namiges Attribut, so wird dessen Wert überschrieben.

Ein kopierter Attributknoten wird bei Vorhandensein eines type- oder vali­dation-Attributs entsprechend geprüft, ein Sequenzkonstruktor im Inneren der Instruktion aber ignoriert. Die Verwendung von Attributsets im Zusam­menhang mit dem Kopieren von Attributknoten ist wiederum nicht möglich; ein gesetztes use-attribute-sets wird auch hier ignoriert.

Anwendung von xsl:copy auf Textknoten:
Der Textknoten wird in die Ergeb­nissequenz kopiert, was der Anwendung von xsl:value-of oder xsl:apply-templates entspricht.

Bindungen von Attributsets an xsl:copy werden ignoriert, ebenso ein eventu­elles type- oder validation-Attribut oder ein Sequenzkonstruktor im Inneren der Instruktion.

Anwendung von xsl:copy auf sonstige Knotentypen:
Namensraumknoten werden in Zusammenhang mit einem kopierten Element mitkopiert, sodass xsl:copy auf sie nicht explizit angewendet werden muss. Kommentar- und Prozessanwendungsknoten werden, sofern xsl:copy auf sie angewendet wird, ebenfalls kopiert. Hierbei muss berücksichtigt werden, dass die eingebauten Template-Regeln diese Knotentypen ignorieren. Es müssen also für diese Kno­tentypen explizite Template-Regeln geschrieben werden, innerhalb derer xsl:copy verwendet wird (siehe Beispiel 5).

Auch für diese Knotentypen wird weder ein Sequenzkonstruktor ausgeführt noch das use-attribute-sets-, das type- oder validation-Attribut beachtet.

Andere Fälle:
Ist das verarbeitete Item kein Knoten, sondern ein atomarer Wert, so wird dieser durch xsl:copy unverändert weitergegeben. Ein potentieller Sequenz­konstruktor in xsl:copy wird in diesem Fall nicht ausgeführt.

Beispiele:

Beispiel 1 – Elemente kopieren:

<xsl:template match="a | b | c">
  <xsl:copy>
    <xsl:value-of select="."/>
  </xsl:copy>
</xsl:template>

Dieses Beispiel kopiert Elemente <a>, <b> oder <c> und mit Hilfe der Instruk­tion xsl:value-of den Stringwert des jeweiligen Elements.

Beispiel 2 – Elemente kopieren mit Attributset:

<xsl:template match="a | b | c">
  <xsl:copy use-attribute-sets="set1 set2 set3"/>
</xsl:template>

Dieses Beispiel kopiert Elemente <a>, <b> oder <c> ins Ergebnisdokument, allerdings nicht deren Inhalte. Die Kopien erhalten jeweils die in den drei ange­gebenen Attributsets enthaltenen Attribute.

Beispiel 3 – Elemente mit allen Attributen kopieren:

<xsl:template match="a | b | c">
  <xsl:copy>
    <xsl:for-each select="@*">
      <xsl:copy/>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>

Dieses Beispiel kopiert mit der äußeren xsl:copy-Instruktion die Elemente <a>, <b> oder <c> und mittels einer Schleife xsl:for-each und einer weiteren xsl:copy-Instruktion jeweils alle Attribute des kopierten Elements.

Beispiel 4 – Tiefe »1 zu 1« -Kopie:

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

Durch rekursives Anwenden können mit xsl:copy auch »tiefe« Kopien erzeugt werden. Das Beispiel-Template kopiert mit xsl:copy alle Knoten auf der Child- und Attributachse. Anschließend ruft es sich selbst wieder auf, um die Knoten der nächsten Ebene zu erfassen. Durch die Möglichkeit, im Inneren von xsl:copy die weiterzuverarbeitenden Knoten genauer zu spezifizieren, ist die­ses Verfahren zur Erstellung tiefer Kopien besser steuerbar als das pauschalere mittels xsl:copy-of.

Beispiel 5 – Kommentare und Prozessanweisungen kopieren:

<xsl:template match="comment()">
  <xsl:copy/>
</xsl:template>
<xsl:template match="processing-instruction()">
  <xsl:copy/>
</xsl:template>

Der Befehl xsl:copy kann das einfache Kopieren von Kommentaren oder Pro­zessanweisungen ermöglichen – hier werden die eingebauten Default-Templa­te-Regeln (siehe dort) überschrieben. Da Kommentare und Prozessanweisungen keine innere Struktur in Form von Kindelementen besitzen, bietet sich die Ver­wendung von xsl:copy an.

Elementdefinition:

XSLT 1.0:

<!-- Category: instruction -->
<xsl:copy 
     use-attribute-sets = qnames >

     <!-- Content: template -->

</xsl:copy>

XSLT 2.0:

<!-- Category: instruction -->
<xsl:copy
     copy-namespaces? = "yes" | "no"
     inherit-namespaces? = "yes" | "no"
     type? = qname 
     use-attribute-sets? = qnames
     validation? = "strict" | "lax" | "preserve" | "strip">

     <!-- Content: sequence-constructor -->

</xsl:copy>
Tipp der data2type-Redaktion:
Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © Galileo Press, Bonn 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT 2.0 & XPath 2.0 ― Das umfassende Handbuch" denselben Bestimmungen wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Galileo Press, Rheinwerkallee 4, 53227 Bonn