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

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


can be used when the context node in the source document is an attribute node. It's not necessary that the owning element was output using

; for example, the following code ensures that the
width
,
height
, and
depth
attributes of the source

element are copied to the output

element, but its
value
and
owner
attributes are discarded:



   




   



This example uses

to process all the attributes of the

element. Some of these match one template rule, which copies the attribute to the output element, while others match an empty template rule that does nothing.

The same effect could be achieved more easily with

, as follows:


  

    

  


The
select
expression here selects a sequence containing all the
width
,
height
, and
depth
attributes of the context node, and the

instruction copies this sequence. The
,
operator, described in Chapter 10, concatenates two sequences (or in this case, two nodes) to form a single sequence.

If you want to copy all attributes of the current node to the result tree, the simplest way to achieve this is

. If you want to copy all the attributes except certain particular ones, you can use the XPath 2.0
except
operator:


Finally, if you want to add a bundle of commonly used attributes to an element, a convenient mechanism is available in the form of attribute sets. These can be defined using an

declaration, described on page 266.

Creating an Attribute Whose Value Is a QName

XML Schema allows an attribute to have a value whose type is
xs:QName
. A typical example of such an attribute is
xsi:type=“xs:decimal”
, which happens to be an attribute whose meaning is defined in the XML Schema specification itself. But they can also be defined in any other XML vocabulary. In fact, QName-valued elements can also be defined, though I haven't come across them in practice.

If you are generating an XSLT stylesheet as the output of the transformation, you will often have to generate QNames in the content of attributes; not only attributes like the
name
attribute of

and

, but any attribute that contains an XPath expression or a pattern. In fact, any attribute that is an attribute value template can potentially contain a QName.

The tricky thing about these attributes is that they contain a namespace prefix, and you need to ensure that the output document contains a namespace declaration that binds this prefix to the correct URI.

It turns out that the fact that the attribute is declared in the schema as an
xs:QName
doesn't help with this. Firstly, not all these attributes are declared as QNames (some of them contain entire XPath expressions). But even where the type is known to be an
xs:QName
, you can't rely on this to ensure that the right namespaces are declared. This is because the process of creating an attribute node for an element in XSLT is typically:

1.
Evaluate the expression that delivers the attribute value; atomize the result of this expression and convert the resulting sequence to a single string. This process loses any type information associated with the values from which the string was constructed.

2.
Create an attribute node with this string value.

3.
When the attribute is attached to an element, perform namespace fixup on the element. Namespace fixup is described on page 310.

4.
Finally, if required, perform schema validation on the element.

In this process, there is no type annotation associated with the attribute at the time namespace fixup is performed. The namespace nodes need to be in place before validation of the attribute as a QName will succeed, so the only way of constructing them automatically would be to do it during validation, which would require a rewrite of the (already hideously complex) rules defined in XML Schema for validating elements.

The consequence of all this is that when you construct one of these attributes, it is your responsibility firstly to choose a prefix and to output the attribute in its correct lexical form and secondly to ensure that the containing element node has a namespace node that maps this prefix to the required namespace URI. The simplest way to be sure of this is by using the

instruction described on page 390.

So to generate the element
93.7
, write:


  

                 namespace=“http://www.w3.org/2001/XMLSchema-instance”

                 select=“‘xs:decimal’”>

  

                 select=“‘http://www.w3.org/2001/XMLSchema’”/>

  


An alternative to using

, in a case like this where the containing element is generated using a literal result element, is simply to ensure that the literal result element has a namespace node that will be copied to the result tree. This can be achieved by writing:


  

                 namespace=“http://www.w3.org/2001/XMLSchema-instance”

                 select=“‘xs:decimal’”>

  


The cases where

is needed are (a) where the element is produced using

rather than a literal result element and (b) where the namespace prefix or URI is not known at compile time.

Note that it's not a good idea to generate special attributes such as
xsi:type
by including them directly as attributes on the literal result element. This is because if the stylesheet is ever passed through a schema processor, the schema processor will try to check that the content of the

element in the stylesheet is
xs:decimal
, and of course it isn't. You could avoid such problems by using namespace aliasing (see

on page 394), but in my view generating the attribute using

is easier.

Examples

The following example outputs an HTML
element, with a
SELECTED
attribute included only if the boolean variable
$selected
is true. (The XML output would be
SELECTED=“SELECTED”>
, but the HTML output method will convert this to
.)

Example: Generating an Attribute Conditionally

This example shows the use of

in a situation where the attribute is generated only if certain conditions are true in the source data.

Source

The source file is
countries.xml
.



  

  

  

  

  

  

  


Stylesheet

The stylesheet file is
options.xsl
.

This is a complete stylesheet using the simplified stylesheet syntax described in Chapter 3, page 125. It outputs an HTML selection box in which the
selected
attribute is set for the option marked as
selected=“yes”
in the XML source document.

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


Please select a country:



  

    

       selected

    

    

  







Output

The output (shown with the selection box opened) is shown in
Figure 6-1
.

Other books

Fire Baptized by Kenya Wright
Lady of Pleasure by Delilah Marvelle
The Horse Lord by Morwood, Peter
Nonviolence by Mark Kurlansky
Watching Amanda by Janelle Taylor
A Famine of Horses by P. F. Chisholm
Savage Skies by Cassie Edwards
Bet You'll Marry Me by Darlene Panzera
Epic Fail by Claire Lazebnik