Articles
DevASP - ASP and XML Articles, Samples, Toturials, Sample Chapters and resources for Developers Tuesday, February 07, 2012
Home
Articles & Samples
Dev Search
Sample Chapters
Link to US
Contact
Search Directory
Applications
Articles & Samples
Components
Community
Database
Developer Sites
Downloads
Hosting Services
Introduction
Knowledge Base
Sample Chapters
WebCasts
ASP Directory
Applications
Articles & Samples
Components
Developer Sites
Knowledge Base
Sample Chapters
WebCasts
XML Directory
Applications
Articles & Samples
Developer Sites
Error, Bugs & Fixes
Downloads
Introduction
Knowledge Base
Sample Chapters
WebCasts

<xsl:copy> and <xsl:copy-of>


These two elements copy information from a source node directly to the result tree. <xsl:copy> performs what is known as a shallow copy. This means that it copies only the node and any namespace – not its descendants or attributes. <xsl:copy-of> performs a deep copy, copying not only the node and any namespace, but all its attributes and descendants.

 

<xsl:copy-of> is useful for copying sections of the XML source tree unchanged to the result tree, while <xsl:copy> gives more control of what will be copied. For example, we might want to list some key data from Hamlet.xml. We could do this with the following simple stylesheet (Playkey.xsl):

 

<xsl:stylesheet

version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 

<xsl:output method="xml" indent="yes"/>

 

<xsl:template match="text()"/>

 

<xsl:template match="PLAY">

<xsl:copy>


<xsl:apply-templates/>

</xsl:copy>

</xsl:template>

 

<xsl:template match="TITLE | PERSONAE">

<xsl:copy-of select="."/>

</xsl:template>

 

</xsl:stylesheet>

 

The result of this is to copy the element <PLAY> (but not its descendants) to the result tree as the document element, then list the title of the play, the Dramatis Personae, and the title of each Act and Scene. Note that we have used the line:

 

<xsl:template match="text()" />

 

to ensure that the built-in templates do not cause extraneous text to be output. The result when this is applied to Hamlet.xml looks like this:

 

<?xml version="1.0" encoding="utf-8"?>

<PLAY>

<TITLE>The Tragedy of Hamlet, Prince of Denmark</TITLE>

<PERSONAE>

<TITLE>Dramatis Personae</TITLE>

 

<PERSONA>CLAUDIUS, king of Denmark. </PERSONA>

<PERSONA>HAMLET, son to the late, and nephew to the present king.</PERSONA>

<PERSONA>POLONIUS, lord chamberlain. </PERSONA>

<PERSONA>HORATIO, friend to Hamlet.</PERSONA>

<PERSONA>LAERTES, son to Polonius.</PERSONA>

<PERSONA>LUCIANUS, nephew to the king.</PERSONA>

 

<PGROUP>

<PERSONA>VOLTIMAND</PERSONA>

<PERSONA>CORNELIUS</PERSONA>

<PERSONA>ROSENCRANTZ</PERSONA>

<PERSONA>GUILDENSTERN</PERSONA>

<PERSONA>OSRIC</PERSONA>

<GRPDESCR>courtiers.</GRPDESCR>

</PGROUP>

 

<PERSONA>A Gentleman</PERSONA>

<PERSONA>A Priest. </PERSONA>

 

<PGROUP>

<PERSONA>MARCELLUS</PERSONA>

<PERSONA>BERNARDO</PERSONA>

<GRPDESCR>officers.</GRPDESCR>

</PGROUP>

 

<PERSONA>FRANCISCO, a soldier.</PERSONA>

<PERSONA>REYNALDO, servant to Polonius.</PERSONA>

<PERSONA>Players.</PERSONA>


<PERSONA>Two Clowns, grave-diggers.</PERSONA>

<PERSONA>FORTINBRAS, prince of Norway. </PERSONA>

<PERSONA>A Captain.</PERSONA>

<PERSONA>English Ambassadors. </PERSONA>

<PERSONA>GERTRUDE, queen of Denmark, and mother to Hamlet. </PERSONA>

<PERSONA>OPHELIA, daughter to Polonius.</PERSONA>

<PERSONA>Lords, Ladies, Officers, Soldiers, Sailors, Messengers, and other Attendants.</PERSONA>

<PERSONA>Ghost of Hamlet's Father. </PERSONA>

</PERSONAE>

<TITLE>ACT I</TITLE>

<TITLE>SCENE I. Elsinore. A platform before the castle.</TITLE>

<TITLE>SCENE II. A room of state in the castle.</TITLE>

<TITLE>SCENE III. A room in Polonius' house.</TITLE>

<TITLE>SCENE IV. The platform.</TITLE>

<TITLE>SCENE V. Another part of the platform.</TITLE>

<TITLE>ACT II</TITLE>

<TITLE>SCENE I. A room in POLONIUS' house.</TITLE>

<TITLE>SCENE II. A room in the castle.</TITLE>

<TITLE>ACT III</TITLE>

<TITLE>SCENE I. A room in the castle.</TITLE>

<TITLE>SCENE II. A hall in the castle.</TITLE>

<TITLE>SCENE III. A room in the castle.</TITLE>

<TITLE>SCENE IV. The Queen's closet.</TITLE>

<TITLE>ACT IV</TITLE>

<TITLE>SCENE I. A room in the castle.</TITLE>

<TITLE>SCENE II. Another room in the castle.</TITLE>

<TITLE>SCENE III. Another room in the castle.</TITLE>

<TITLE>SCENE IV. A plain in Denmark.</TITLE>

<TITLE>SCENE V. Elsinore. A room in the castle.</TITLE>

<TITLE>SCENE VI. Another room in the castle.</TITLE>

<TITLE>SCENE VII. Another room in the castle.</TITLE>

<TITLE>ACT V</TITLE>

<TITLE>SCENE I. A churchyard.</TITLE>

<TITLE>SCENE II. A hall in the castle.</TITLE>

</PLAY>

 

Of course, we could equally well use the same stylesheet for other plays marked up in the same format.

 

This example shows a common use of <xsl:copy-of>, but perhaps a rather contrived example for <xsl:copy>, since we could equally well have used a different template for the <PLAY> element:

 

<xsl:template match="PLAY">

<PLAY>

<xsl:apply-templates/>

</PLAY>

</xsl:template>

 

This would also have allowed us to use a different element name in the result tree from that in the source tree. So let's look at another use of <xsl:copy>.

 

We said earlier that <xsl:copy> gives us more control over the copying operation than <xsl:copy-of>. We used this just now to control which descendants of the <PLAY> element we would copy. Another use is if we have a source tree that is mainly XHTML, but with some additional elements from a different namespace. Much of the web site at http://www.alphaxml.com is written in XHTML. However, there is a glossary application that is used to explain technical terms. An example of the source code that might be used on this site is:


 

<p>The <em>Extensible Markup Language</em> provides a universal mechanism for marking up data on the web. Unlike <g:term>HTML</g:term>, which is a language based around displaying data in a web browser, <g:term>XML</g:term> puts no constraints on the purpose for which the data will be used, but merely describes the structure of the data. XML can therefore be used (and is used) for any application that involves the transfer of data across the web for either display or computation purposes.</p>

 

Here, the <p> and <em> elements are from the XHTML namespace, which is used as the default for the document. The <term> element is from a different namespace for the glossary, using the prefix g.

 

When we process this, we want to copy the XHTML elements unchanged, but carry out some additional processing on the <g:term> elements. <xsl:copy> lets us do this. This is an extract from the template used on that site (reformatted for display):

 

<xsl:template match="*|@*|text()">

<xsl:copy>

<xsl:apply-templates select="*|@*|text()" />

</xsl:copy>

</xsl:template>

 

<xsl:template match="g:term">

<a target="_blank" class="glossary">

<xsl:attribute name="href">

glossary/glossary.asp?glossary=AlphaGlossary.xml&amp;term=

<xsl:value-of select="."/>

</xsl:attribute>

<xsl:value-of select="."/>

</a>

</xsl:template>

 

In this example, the first template will be run for all elements, attributes and text nodes apart from the <g:term> element (for which the second template takes priority). This will copy the node to the result tree and apply templates for its children. If one of those children is a <g:term> element, the second template will be run. This simply creates an anchor (<a>) element in the result tree with an href attribute whose value depends on the enclosed text. For the term "HTML", the result will be:

 

<a

target="_blank"

class="glossary

href="glossary/glossary.asp?glossary=AlphaGlossary.xml&amp;term=HTML">

HTML

</a>



DevASP - Privacy - Disclaimer
Copyright © 2008 DevASP.com