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

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

The local part of the name of the created attribute node will always be the same as the local part of the
QName
supplied as the value of the
name
attribute.

If the

instruction has a
namespace
attribute, it is evaluated (expanding the attribute value template if necessary) to determine the namespace URI part of the name of the created attribute node:

  • If the value is a zero-length string, the attribute will have a null namespace URI. It will therefore be serialized without a prefix. Any prefix in the value of the
    name
    attribute will be ignored.
  • Otherwise, the value should be a URI identifying a namespace. This namespace will be used as the namespace URI of the new attribute node. This namespace does not need to be in scope at this point in the stylesheet, in fact it usually won't be. The system may report an error if the namespace isn't a valid URI. The namespace URI associated with any prefix in the
    QName
    obtained from the
    name
    attribute will be ignored.

If there is no
namespace
attribute:

  • If the supplied
    QName
    includes a prefix, the prefix must be a namespace prefix that is in scope at this point in the stylesheet: In other words, there must be an
    xmlns:prefix
    declaration either on the

    instruction itself or on some containing element. The namespace URI in the output will be that of the namespace associated with this prefix in the stylesheet.
  • Otherwise, the attribute will have a null namespace URI. The default namespace is
    not
    used.

Where possible, the prefix of the attribute name (or the absence of a prefix) will be taken from the prefix given in the
name
attribute. However, if it isn't possible to use this prefix, then the namespace fixup process (described on page 310) will allocate a different prefix. This arises, for example, if two attributes of the same element use the same prefix to refer to different namespaces, or if the attribute is in a namespace but no prefix is supplied, or if a reserved prefix such as
xml
or
xmlns
is used.

Namespace fixup is not performed at the level of an individual attribute node. This is because attributes can only be associated with namespace nodes via their parent element.

If the
name
attribute provides a name that has no prefix, but a
namespace
attribute is present so that the namespace URI is not null, then the system has no choice but to invent a namespace prefix for the attribute. For example, if you write:


  

    200

  


then the output might be:


The XSLT specification explicitly states that you cannot use

to generate namespace declarations by giving an attribute name of
xmlns
or
xmlns:*
. In the XPath data model, attributes and namespaces are quite different animals, and you cannot simulate a namespace declaration by creating an attribute node with a special name. Namespace declarations will be added to the output automatically whenever you generate elements or attributes that require them, and if you really need to, you can also force them to be generated using the

instruction.

Using the New Attribute Node

The new attribute node, when initially created, has no parent node. Usually, however, the result of the instruction will form part of a sequence that is used to construct the content of a new element node. This will always be the case when the parent of the

instruction is an

or

instruction, or a literal result element, and it will also be the case when the

is contained in an

.

Very often the

instruction will be contained directly in the instruction that writes the element; for example:


   2


but this is not essential, for example you could also do:


   


and then create the attribute from within the
set-border
template. Less commonly, parentless attribute nodes may be created and held in variables, for example:


  red

  green

  blue


In this particular case, just to show what is possible, we have created a variable whose value is a sequence of three parentless attributes, each of which has the same attribute name. These attributes could later be added to elements using instructions such as:


   


Whether the attribute node is added immediately to an element, or whether it is perhaps stored in a variable and added to an element later, at the point where the attribute is attached to an element, it must appear in the sequence before any child nodes (text nodes, elements, comments, or processing instructions) that are being added to the same element node.

This rule is there for the convenience of implementors. It means that the XSLT processor can execute the stylesheet and build the result tree sequentially, if it wishes. If it does so, the attributes for an element will always be evaluated before the children of the element, which means that the processor doesn't actually need to build the result tree in memory. Instead, each node can be serialized to an XML file as soon as it is generated. If it weren't for this rule, the software wouldn't be able to write the first start tag until right at the end, because there would always be a chance of an attribute being added to it.

When a sequence of nodes containing several attribute nodes is used to form the content of an element, and several of the attributes have the same name, the one that is used is the one that appears last in the sequence. This is not an error: in fact, when named attribute sets are used to add attributes to an output element, it is an important mechanism. Named attribute sets are described under

on page 266.

XQuery does this differently. In XQuery 1.0, adding two attributes with the same name to the same element is an error.

The Value of the Attribute

The string value of the new attribute node is obtained by evaluating the
select
attribute or the sequence constructor. The value of the
separator
attribute, if present, also plays a role.

Whether the
select
attribute or the sequence constructor is used, it is evaluated to produce a sequence of items, and this sequence of items is processed as follows:

1.
Adjacent text nodes in the sequence are merged, and zero-length text nodes are removed.

2.
The sequence is atomized. Atomization is described in Chapter 2 (page 81). This process replaces any nodes in the sequence by their typed values.

3.
Every value in the atomized sequence is converted to a string by applying the XPath casting rules.

4.
The strings in the resulting sequence are concatenated, with an optional separator between adjacent strings. If the
separator
attribute is present, its value is used as the separator (this may be a zero-length string). If the
select
attribute is used, then the default separator is a single space; otherwise, it is a zero-length string—in other words, there is no separator.

5.
The resulting string is used as the value of the new attribute node.

Other books

Girl in the Moonlight by Charles Dubow
Truth and Dare by Candace Havens
The Rancher's Bride by Dina Chapel
The Gift by Danielle Steel
Dawn of Empire by Sam Barone
Through Indigo's Eyes by Tara Taylor
Bodyguard: Ransom (Book 2) by Chris Bradford
Observe a su perro by Desmond Morris