XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition (151 page)

BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition
13.5Mb size Format: txt, pdf, ePub

Usage and Examples

There are two principal uses for

: it can be used when copying data to and from a temporary tree, and it can be used for copying a subtree unchanged from the input document to the output.

Copying Nodes to and from Temporary Trees

One use of

in conjunction with temporary trees arises when you want to write the same collection of nodes to the output in more than one place. This might arise, for example, with page headers and footers. The construct allows you to assemble the required output fragment as the value of a variable and then copy it to the final output destination as often as required.

Example: Usingfor Repeated Output

This example constructs a table heading in a variable and then copies it repeatedly each time a new table is created.

Source

The source file
soccer.xml
holds details of a number of soccer matches played during the World Cup finals in 1998.




  1998-06-10

  Brazil

  Scotland



  1998-06-10

  Morocco

  Norway



  1998-06-16

  Scotland

  Norway



  1998-06-16

  Brazil

  Morocco



  1998-06-23

  Brazil

  Norway



  1998-06-23

  Scotland

  Morocco



Stylesheet

The stylesheet is in the file
soccer.xsl
.

It constructs an HTML table heading as a global tree-valued variable, and then uses

every time it wants to output this heading. In this particular case the heading is fixed, but it could contain data from the source document, as long as the heading is the same each time it is output. If it contained calculated values, there would be a possible performance benefit by coding it this way rather than regenerating the heading each time.

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


    

        Date

        Home Team

        Away Team

        Result

    




    Matches in Group 

    

    

    

               

        

        

          select=“format-date(date, ‘[D] [MNn,1-3] [Y]’)”/>

        

          

        

          select=“team[1]/@score, ‘-’, team[2]/@score” separator=“”/>  

               

    

      




Output

(Apologies to soccer fans who know that all these matches were played in France, on neither team's home territory. It's only an example!) See
Figure 6-2
.

Deep Copy

The other use for

is that it provides a simple way of copying an entire subtree of the input document directly to the output. As

does a deep copy, this is simpler than using

, although it can only be used when the whole subtree is to be copied without change. For example, an XML document defining a product description might have an element called

whose content is pure XHTML. You could copy this to the output HTML document with a template rule such as:


   


      

   



Unlike the examples using

, there is no recursive application of template rules here: each child node of the

element is copied to the output destination in a single operation, along with all its children.

The most common example of this technique is using

to copy all the attributes of the current element. You can also use this selectively. To copy specific attributes use the following code:


Copying all the attributes with specific exceptions is also straightforward using the new
except
operator in XPath 2.0:


Using

only works if you want an exact copy of the subtree. If you want to change anything, for example removing some nodes or changing the namespace URI of the element names, you will need to walk the tree using a modified identity template as described under

on page 287.

Copying Namespace Nodes

The
copy-namespaces
attribute provides a choice as to whether the namespace nodes in a tree are copied or not. By default, all the namespaces are copied.

If namespaces are used only in the names of elements and attributes, then there is no need to copy namespace nodes. In the new tree, all the necessary namespace nodes will be created by virtue of the namespace fixup process, which is described under

on page 306 but applies equally to elements constructed using

or

. Copying unwanted namespace nodes generally does no harm, but they are unnecessary and can clutter the result document, and in some cases they can cause DTD-based validation to fail.

The real problem arises when namespace prefixes are used in the values of attributes or text nodes. This happens, for example, if the document is an XSLT stylesheet containing XPath expressions, if it is an XML Schema, if it uses
xsi:type
attributes that identify schema-defined types (the value of this attribute is a QName, and therefore contains a namespace prefix), or if it uses any other XML vocabulary that contains references to the names of elements or attributes within the document content. Since the XSLT processor cannot know that these references exist, and since the references depend on the existence of namespace nodes to resolve namespace prefixes to a URI, it is unsafe to shed the namespace nodes.

There are some cases where losing namespace nodes is very desirable. For example, if an XML document is wrapped in a SOAP envelope and then subsequently removed from the envelope, the round trip can easily cause the SOAP namespaces defined for use in the envelope to stick to the content when it is extracted using

. Under these circumstances, using
copy-namespaces=“no”
can be useful to remove unwanted namespaces from the result. But it is only safe to use this option if you know that there are no namespace prefixes in the content of text nodes and attribute nodes.

Other books

Kiss & Sell by Brittany Geragotelis
El socio by Jenaro Prieto
Gill Man's Girl by Carolina Connor
Beastly Desires by Winter, Nikki
The Colonel's Man by Mina Carter, J. William Mitchell
El castillo de Llyr by Lloyd Alexander
The Jerusalem Diamond by Noah Gordon