XSL-Übersicht / xsl:copy, xsl:copy-of

xsl:copy, xsl:copy-of

xsl:copy, xsl:copy-of

xsl:copy generiert eine flache Kopie eines jeweils aktuellen Knotens. xsl:copy-of generiert eine tiefe Kopie eines jeweils aktuellen Knotens.

xsl:copy

Bei xsl:copy wird eine flache Kopie eines jeweils aktuellen Knotens erstellt, d.h. ohne seine Childnodes: das heißt auch ohne seinen Textinhalt.


 <xsl:template match="/">   
  <ergebnis>
   <xsl:for-each select="//Ort/name">
    <xsl:copy/>
   </xsl:for-each>   
  </ergebnis>
 </xsl:template>

Das Ergebnis dieser Aktion sehen Sie hier:


<ergebnis>
   <name/>
   <name/>
   <name/>
</ergebnis>

Ist dem Knoten ein Namespace zugeordnet, so wird auch dieser mitkopiert. Das Attribut copy-namespaces, das erst seit XSLT 2.0 besteht und die Werte (true | false | no | yes ) beinhalten kann (in XSLT 3.0 kommen noch die Alternativen 0 | 1 hinzu), entscheidet, ob auch die dem Element zugehörigen Namensraumknoten mitkopiert werden.

Betrachten Sie das folgende XML-Dokument:


<ns1:Orte 
  xmlns="www.wilfried-grupe.de/Beispiele/2018" 
  xmlns:ns1="www.wilfried-grupe.de/Orte/2018"
  xmlns:ns2="www.wilfried-grupe.de/Ort">
  <ns2:Ort>
    <id>1</id>
    <name>Neustadt</name>
  </ns2:Ort>
</ns1:Orte>

Nun verarbeiten Sie das XML-Dokument mit diesem Template:


<xsl:template match="/">   
    <ergebnis>
        <xsl:for-each 
            select="//*[local-name() = 'Orte']">
            <xsl:copy copy-namespaces="no"/>
        </xsl:for-each>   
    </ergebnis>
</xsl:template>

Der Default-Wert für copy-namespaces ist true: Dann werden alle relevanten Namensraumknoten mitkopiert.


<ergebnis>
   <ns1:Orte xmlns="www.wilfried-grupe.de/Beispiele/2018"
             xmlns:ns1="www.wilfried-grupe.de/Orte/2018"
             xmlns:ns2="www.wilfried-grupe.de/Ort"/>
</ergebnis>

Beim Aufruf von copy-namespaces='no' wird nur der aktuelle Namensraumknoten wiedergegeben.


<ergebnis>
   <ns1:Orte xmlns:ns1="www.wilfried-grupe.de/Orte/2018"/>
</ergebnis>

xsl:copy-of

Im Gegensatz zur flachen Kopie bei xsl:copy handelt es sich bei xsl:copy-of um die tiefe Kopie eines Knotens, mit allen descendant-, Text-, Attribut-, Kommentar- und Processing-Instructions-Knoten. Siehe auch .


<xsl:template match="/">   
    <ergebnis>
        <xsl:for-each 
             select="//*[local-name() = 'Orte']">
            <xsl:copy-of 
                select="." 
                copy-namespaces="no"/>
        </xsl:for-each>   
    </ergebnis>
</xsl:template>

Auch hier gibt es die Möglichkeit, via copy-namespaces die Ausgabe der Namespaces zu beeinflussen.

Bei copy-namespaces='no' erhält jeder Childnode seinen Namespace als lokalen Default-Namespace. Der Aufruf des oben beschriebenen Templates mit copy-namespaces='no' hat dieses Ergebnis:


<ergebnis>
 <ns1:Orte xmlns:ns1="www.wilfried-grupe.de/Orte/2018">
  <ns2:Ort xmlns:ns2="www.wilfried-grupe.de/Ort">
   <id xmlns="www.wilfried-grupe.de/Beispiele/2018">1</id>
   <name xmlns="www.wilfried-grupe.de/Beispiele/2018">Neustadt</name>
  </ns2:Ort>
 </ns1:Orte>
</ergebnis>

copy-namespaces='yes' hat zur Wirkung, dass alle Namensraumknoten im jeweiligen Knoten einmal abgebildet werden. Der Aufruf des oben beschriebenen Templates mit copy-namespaces='yes' hat daher dieses Ergebnis:


<ergebnis>
 <ns1:Orte xmlns="www.wilfried-grupe.de/Beispiele/2018"
           xmlns:ns1="www.wilfried-grupe.de/Orte/2018"
           xmlns:ns2="www.wilfried-grupe.de/Ort">
    <ns2:Ort>
       <id>1</id>
       <name>Neustadt</name>
    </ns2:Ort>
 </ns1:Orte>
</ergebnis>

Verwendung findet xsl:copy-of häufig beim Aufbau temporärer XML-Bäume, die quasi eine Zwischenkonvertierung darstellen, von denen sich dann effizienter weiterarbeiten lässt.

Der Variablen vtmpcopy werden eine ganze Anzahl von Childnodes Mensch zugewiesen, deren vorname einem bestimmten Pattern entspricht. Neben dem vorname stehen aber auch alle weiteren descendant-Nodes bereit.


<xsl:variable name="vtmpcopy">
 <xsl:for-each 
      select="//Mensch[matches(vorname, '[H][a-z]+')]">
  <xsl:copy-of select="." />
 </xsl:for-each>
</xsl:variable>

Im eigentlichen Aufruf kann dieser temporäre Baum gezielt ausgewertet werden:


<xsl:template match="/">   
 <ergebnis>
  <xsl:for-each 
       select="$vtmpcopy/Mensch">
   <vn>
    <xsl:value-of 
         select="vorname"/>
   </vn>
  </xsl:for-each>   
 </ergebnis>
</xsl:template>

Und das Ergebnis sieht dann so aus:


<ergebnis>
   <vn>Hugo</vn>
   <vn>Heini</vn>
   <vn>Horst</vn>
</ergebnis>

wg / 5. 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/copy_of.html