xsl:copy


The <xsl:copy> instruction copies the context node in the source document to the result sequence. This is a shallow copy; it does not copy the children, descendants, or attributes of the context node, only the context node itself and (if it is an element) its namespaces. For a deep copy, you need to use <xsl:copy-of> , see page 245.

Changes in 2.0

A new attribute copy-namespaces has been added, which allows control over whether namespace nodes for an element should be copied or not.

New attributes validation and type have been added to control whether and how the copied element is validated against a schema.

Format

 <xsl:copy   copy-namespaces? = "yes"  "no"   use-attribute-sets? = qnames   validation? = "strict"  "lax"  "preserve"  "strip"   type? = qname>   <!-- Content: sequence-constructor --> </xsl:copy> 

Position

<xsl:copy> is an instruction. It is always used within a sequence constructor.

Attributes

Name

Value

Meaning

copy-namespaces

optional

«yes » or «no »

Indicates whether the namespace nodes of an element should be copied; default is «yes »

use-attribute-sets

optional

Whitespace-separated list of lexical QNames

The names of attribute sets to be applied to the generated node, if it is an element

validation

optional

«strict » , «lax » , «preserve » , or «skip »

Indicates whether and how the copied nodes should be subjected to schema validation, or whether existing type annotations should be retained or removed

type

optional

Lexical QName

Identifies a type declaration (either a built-in type, or a user -defined type imported from a schema) against which copied nodes are to be validated

Content

An optional sequence constructor, which is used only if the item being copied is a document node or an element.

Effect

The action depends on what kind of node the context node is, as follows :

Node kind

Action

document

A new document node is added to the result sequence. The sequence constructor is evaluated to provide the content for the document node. This works in the same way as the content of an <xsl:document> instruction, as described on page 242. The attributes use-attribute-sets and copy-namespaces are ignored. The type and validation attributes have the same effect as <xsl:document> .

element

An element node is added to the result sequence, as if by a call on <xsl:element> . This will have the same name as the context node. Although the local name and namespace URI are guaranteed to be the same as the original, the prefix may change. The namespace nodes associated with the current element node are also copied, unless «copy-namespaces="no" » is specified.

The use-attribute-sets attribute is expanded: It must be a whitespace-separated list of QNames that identify named attribute sets in the stylesheet. The attributes within these named attribute sets are evaluated in the order they appear, and added to the new element node. The sequence constructor is then evaluated.

Namespace fixup is applied to the new element, to ensure that it has all the namespace nodes it needs, in the same way as for the <xsl:element> instruction.

With a schema-aware processor, the new element may be validated and may acquire a type annotation: This depends on the values of the type and validation attributes, and works exactly as for <xsl:element> described on page 260. Note the surprising consequence that «validation="preserve" » does not cause the type annotation of the original element to be retained: This is not feasible , because the content of the element is not being copied.

text

A new text node is added to the result sequence, with the same string value as the context node. The attributes use-attribute-sets , copy-namespaces , type and validation , and the sequence constructor are ignored

attribute

A new attribute node is added to the result sequence, as if by a call on <xsl:attribute> . This will have the same name and value as the context node. The use-attribute-sets and copy-namespaces attributes and the sequence constructor are ignored. Although the local name, namespace URI, and string value of the output attribute are guaranteed to be the same as the original, the prefix may change (for example, if two attributes added to the same element use the same prefix to refer to different namespace URIs)

With a schema-aware processor, the new attribute may be validated and may acquire a type annotation: This depends on the values of the type and validation attributes, and works exactly as for <xsl:attribute> described on page 201.

processing instruction

A processing instruction node is added to the result sequence, with the same name and value (target and data in XML terminology) as the context node. The attributes use-attribute-sets , copy-namespaces , type , and validation , and the sequence constructor are ignored

comment

A comment node is added to the result sequence, with the same content as the context node. The attributes use-attribute-sets , copy-namespaces , type , and validation , and the sequence constructor are ignored

namespace

The namespace node is copied to the result sequence. The new namespace node will have the same name and value (that is, the same namespace prefix and URI) as the original. The attributes use-attribute-sets , copy-namespaces , type , and validation , and the sequence constructor are ignored

Usage

The main use of <xsl:copy> is when doing an XML-to-XML transformation in which parts of the document are to remain unchanged. It is also useful when the source XML document contains XHTML fragments within it, for example if the simple HTML formatting elements such as <i> and <b> are used within textual data in the source, and are to be copied unchanged to an HTML output document.

Although <xsl:copy> does a shallow copy, it is easy to construct a deep copy by applying it recursively. The typical manner of use is to write a template rule that effectively calls itself:

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

This is sometimes referred to as the identity template. This template rule matches any node except a namespace or document node. This is because «@* » matches any attribute node, and «node() » , which is short for «child::node() » , matches any node that is allowed to be the child of something (that is, an element node, text node, comment, or processing instruction). Once this template rule is applied to a node, it copies that node, and if it is an element node, it copies its attributes unchanged and then applies itself to its child nodes-on the assumption that there is no other template rule with mode="copy" that has a higher priority.

An easier way of doing a deep copy is to use <xsl:copy-of> . However, the recursive use of <xsl:copy> allows modifications to be made to the tree while it is being copied, by adding further template rules. For example, if you want to copy the whole document except for the subtree rooted at a <note> element, you can achieve this with a stylesheet that contains the identity template as above, together with the rule:

  <xsl:template match="note" mode="copy"/>  

which does nothing when a <note> element is found. Because it does nothing, nothing is written to the result tree, so the <note> element is effectively deleted.

Examples

The following template rule is useful if the source document contains HTML-like tables that are to be copied directly to the output, without change to the structure.

  <xsl:template match=" table  tbody  tr  th  td ">   <xsl:copy>   <xsl:copy-of select="@*"/>   <xsl:apply-templates/>   </xsl:copy>   </xsl:template>  

The effect is that all of these elements are copied to the output destination, along with their attributes, but their child elements are processed using whatever template rule is appropriate, which might be the same one in the case of a child element that is part of the table model, or it might be a different template for some other element.

The following template rule matches any elements in the source document that are in the SVG namespace, and copies them unchanged to the output, along with their attributes. The SVG namespace node itself will also be included automatically in the output tree. (SVG stands for Scalable Vector Graphics, which is an XML-based standard that became a W3C Recommendation on September 4, 2001, and was designed to fill the long-standing need for including vector graphics in Web pages.)

  <xsl:template match="svg:*"   xmlns:svg="http://www.w3.org/2000/svg">   <xsl:copy copy-namespaces="no">   <xsl:copy-of select="@*">   <xsl:apply-templates/>   </xsl:copy>   </xsl:template>  

This example uses «copy-namespaces="no" » to avoid copying the namespace nodes attached to the SVG elements. It is safe to do this because SVG elements and attributes do not include data that depends on in-scope namespaces. The namespaces used in the element and attribute names will automatically acquire namespace nodes as a result of the namespace fixup process described on page 265. It may be useful to get rid of extraneous namespace nodes. For example, if the SVG document was embedded in an XHTML document, and the purpose of the copy operation is to make it into a free-standing SVG document, then the default value «copy-namespaces="yes" » would mean that the free-standing SVG document would contain an unwanted reference to the XHTML namespace.

See Also

<xsl:copy-of> on the opposite page.




XSLT 2.0 Programmer's Reference
NetBeansв„ў IDE Field Guide: Developing Desktop, Web, Enterprise, and Mobile Applications (2nd Edition)
ISBN: 764569090
EAN: 2147483647
Year: 2003
Pages: 324

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net