xsl:attribute


The <xsl:attribute> instruction constructs an attribute node and adds it to the result sequence.

Changes in 2.0

The content of the attribute can be specified using a select attribute, as an alternative to using a sequence constructor. The separator attribute can be used to format the attribute value when the content is supplied as a sequence.

With a schema-aware XSLT processor, the type and validation attributes can be used to control the type annotation given to the new attribute node.

Format

 <xsl:attribute   name = { qname }   namespace? = { uri-reference }   select? = expression   separator? = { string }   validation? = "strict"  "lax"  "preserve"  "strip"   type? = qname>   <!-- Content: sequence-constructor --> </xsl:attribute> 

Position

<xsl:attribute> may be used either as an instruction within a sequence constructor, or within an <xsl:attribute-set> element.

Attributes

Name

Value

Meaning

name

mandatory

Attribute value template returning a lexical QName

The name of the attribute node to be generated

namespace

optional

Attribute value template returning a URI

The namespace URI of the generated attribute node

select

optional

Expression

Provides the value of the attribute

separator

optional

Attribute value template returning a string

Separator string to be inserted between items when the value is a sequence

validation

optional

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

Indicates whether and how the attribute should be subjected to schema validation

type

optional

lexical QName

Identifies a type declaration (either a built-in type, or a user -defined type imported from a schema) against which the new element is to be validated

The type and validation attributes are mutually exclusive: If one is present, the other must be absent.

Content

A sequence constructor.

Effect

The effect of this instruction is to create a new attribute node, and to return this node as the result of the instruction. In some error cases, the results may be different: These situations are described below.

In the usual case where the sequence constructor containing the <xsl:attribute> instruction is used to construct the content of an element, the attribute must not be preceded in the result sequence by any node other than a namespace node or another attribute node. The processor can either treat this as a fatal error, or discard the attribute node.

The name of the generated attribute node is determined using the name and namespace attributes. The way in which these attributes are used is described below in the section The Name of the Attribute.

The value of the new attribute node may be established either using the select attribute, or using the sequence constructor contained in the <xsl:attribute> instruction. These are mutually exclusive: If the select attribute is present, the <xsl:attribute> element must be empty. If neither is present, the value of the attribute will be a zero-length string. The way the value of the attribute is established is described in more detail in the section The Value of the Attribute.

When a schema-aware XSLT processor is used, the new attribute may be validated to ensure that it conforms to a type defined in a schema. This process results in the new attribute node having a type annotation. The type annotation affects the behavior of subsequent operations on this attribute node even though it is not visible when the result tree is serialized as raw XML. The validation and annotation of the new attribute node are controlled using the type and validation attributes. This is described in the section Validating and Annotating the Attribute.

The Name of the Attribute

The name of an attribute node has two parts : the local name and the namespace URI. These are controlled using the name and the namespace attributes.

Both the name and the namespace attributes may be given as attribute value templates; that is, they may contain expressions nested within curly braces. One of the main reasons for using the <xsl:attribute> instruction in preference to attributes on a literal result element (described in the section Literal Result Elements in Chapter 3, page 106) is that <xsl:attribute> allows the name of the attribute node to be decided at runtime, and this is achieved by using attribute value templates in these two attributes.

The result of expanding the name attribute value template must be a lexical QName ; that is, a valid XML name with an optional namespace prefix, for example, «code » or «xsi:type » . If there is a prefix, it must correspond to a namespace declaration that is in scope at this point in the stylesheet, unless there is also a namespace attribute, in which case it is taken as referring to that namespace.

If the name is not a valid QName , the XSLT processor can either report the error, or ignore it and continue processing. If the error is ignored, the <xsl:attribute> instruction returns an empty sequence.

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 <xsl:attribute> 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. The namespace URI associated with any prefix in the QName obtained from the name attribute will then be ignored (though it must still be valid). This namespace does not need to be in scope at this point in the stylesheet, in fact it usually won't be. The system does not check that the value conforms to any particular URI syntax, so in effect any string can be used.

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 <xsl:attribute> 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.

Attribute nodes, according to the formal data model, do not contain a namespace prefix, only a namespace URI and a local name. The only way to establish a prefix is to look at the namespace nodes for the element node that is the parent of this attribute, to find one that binds a prefix to the namespace URI of this attribute. These namespace nodes are created by virtue of the namespace fixup process that occurs whenever an element node is created: For a description of this process, see page 265.

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. In consequence, if you call the name() function on an attribute node that has not yet been attached to an element, any prefix in the returned name will be meaningless. It's better to use the node-name() function instead: This returns an xs:QName value that can be properly compared with other xs:QName values, without relying on unpredictable namespace prefixes.

In principle, XSLT processors can choose any prefix they like when generating namespace nodes during the namespace fixup process. (Choosing a prefix in this discussion also includes the option of using the empty prefix, which is how the data model represents the default namespace.) In practice, processors will usually be able to make a sensible choice, resulting in prefixes that are recognizable to users, rather than random alphanumeric noise. For example, if the lexical QName used as the value of the name attribute of <xsl:attribute> includes a prefix, then most processors will choose this prefix during the namespace fixup process. Occasionally a processor might choose a different prefix:

  • There might be another prefix available that is just as good. For example, if two attributes on the same element use the same namespace URI, then it makes sense to give both the same prefix.

  • The preferred prefix might already be in use to refer to a different namespace URI. For example, two <xsl:attribute> instructions can create attributes for the same element that are in different namespaces, and in this case they must also have different prefixes. Conflicts are unlikely to happen, but when they do, the system has to invent an arbitrary prefix such as «ns0001 » .

  • Some prefixes, notably «xml » and «xmlns » are reserved.

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:

  <table>   <xsl:attribute name="width" namespace="http://acme.org/">   <xsl:text>200</xsl:text>   </xsl:attribute>   </table>  

then the output might be

  <table ns0001:width="200" xmlns:ns0001="http://acme.org"/>  

The XSLT specification explicitly states that you cannot use <xsl:attribute> 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 <xsl:namespace> instruction.

The new attribute, 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 <xsl:attribute> instruction is an <xsl:element> or <xsl:copy> instruction, or a literal result element, and it will also be the case when the <xsl:attribute> is contained in an <xsl:attribute-set> .

Very often the <xsl:attribute> instruction will be contained directly in the instruction that writes the element, for example:

  <table>   <xsl:attribute name="border">2</xsl:attribute>   </table>  

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

  <table>   <xsl:call-template name="set-border"/>   </table>  

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:

  <xsl:variable name="three-atts" as="attribute()*">   <xsl:attribute name="color">red</xsl:attribute>   <xsl:attribute name="color">green</xsl:attribute>   <xsl:attribute name="color">blue</xsl:attribute>   </xsl:variable>  

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:

  <table>   <xsl:copy-of select="$three-atts[2]"/>   </table>  

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 therefor 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 <xsl : attribute-set> on page 214.

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. The sequence is atomized. Atomization is described in Chapter 2 (page 73). This process replaces any nodes in the sequence by their typed values.

  2. Every value in the atomized sequence is converted to a string by applying the XPath casting rules. An error may occur if there are values that cannot be converted to strings ( specifically , xs : NOTATION or xs : QName values).

  3. 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.

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

The following examples illustrate the effect:

Instruction

Result

 <xsl:attribute name="x"                select="1 to 5"/> 
 x="1 2 3 4 5" 
 <xsl:attribute name="x">   <xsl:sequenceselect="1 to 5"/> </xsl  :  attribute> 
 x="12345" 
 <xsl:attribute name="x"           select="1 to 5"           separator=","/> 
 x="1, 2, 3, 4, 5" 
 <xsl  :  attribute name="x"                 separator="-">   <xsl:sequence select="1 to 5"/> </xsl:attribute> 
 x="1-2-3-4-5" 

In XSLT 1.0, it was an error if the evaluating the content of an attribute produced a node other than a text node. Processors were allowed to recover by ignoring such nodes. In XSLT 2.0, any kind of node is allowed, and is handled by the atomization process. If your stylesheet contains this error, and your XSLT 1.0 processor chose to ignore it, then it will produce different results under XSLT 2.0.

Validating and Annotating the Attribute

This section is relevant only if you are using a schema-aware XSLT processor. With a non-schema-aware processor, you cannot use the type and validation attributes, and the type annotation on the new attribute node will always be xdt:untypedAtomic , which you can effectively ignore because it imposes no constraints.

With a schema-aware processor, you can validate the new attribute to ensure that it conforms to relevant definitions in a schema. If validation fails, a fatal error is reported . If it succeeds, the new attribute node will have a type annotation that reflects the validation that was performed. This type annotation will not affect the way the attribute node is serialized, but if you want to do further processing on the attribute, the type annotation may affect the way this works. For example, if you sort a sequence of attributes annotated with type xs:integer , you will get different results than if they are annotated as xs:string .

If you use the type attribute, the value of the attribute must be a lexical QName that identifies a known type definition. Generally this means that it must either be a built-in type such as xs:string or xs:dateTime , or it must be the name of a global simple type defined in a schema that has been imported using an <xsl:import-schema> declaration in the stylesheet. (That is, the local part of the QName must match the name attribute of a top-level <xs:simpleType> element in the schema for the namespace that matches the namespace URI part of the QName.)

The XSLT specification allows the implementation to provide other ways of accessing type definitions, perhaps through an API or configuration file, and it also allows the type definition to originate from a source other than an XML Schema, but since it provides no details of how this might work, we won't explore the possibility further.

The processor validates that the value of the new attribute node conforms to the named type definition. If it does, the attribute is annotated with the name of this type. If it doesn't, processing fails.

Validating an attribute using the type attribute places no constraints on the name of the attribute. It doesn't need to be an attribute name that is defined in any schema, and it does not matter whether or not the attribute name is in a namespace. The validation is concerned with the content of the attribute and not with its name.

In contrast, validation using the validation attribute is driven by the attribute's name.

For symmetry with other instructions, the validation attribute has four possible values: «preserve » , «strip » , «strict » , and «lax » . However, in the case of <xsl:attribute> , «preserve » and «strip » have exactly the same effect: No validation takes place, and the type annotation on the attribute node will be xdt:untypedAtomic . Let's focus on the other two options.

  • «validation="strict" » causes the processor to look for an attribute declaration that matches the name of the attribute. That is, it looks for a top-level <xs:attribute> whose name attribute matches the local name of the attribute being validated, in a schema whose namespace matches the namespace URI of the attribute being validated. If it can't find such a definition, a fatal error is reported. Otherwise, the value of the attribute node is validated against the schema-defined rules implied by this attribute declaration. Note that global attribute declarations are used only for namespace-qualified attribute names , so this facility has rather limited use.

  • If the attribute declaration in the schema refers to a named type definition, then on successful validation, the attribute is annotated with this type name. If the attribute declaration contains an inline (and therefore unnamed) type definition, the XSLT processor invents a name for this implicit type, and uses this invented name as the type annotation, just as in the case described earlier for the type attribute.

  • «validation="lax" » behaves in the same way as «validation="strict" » , except that no failure occurs if the processor cannot locate a top-level schema definition for the attribute. Instead of reporting an error, the attribute is annotated as xdt:untypedAtomic .

If neither the type nor validation attribute is present, then the system behaves as if the validation attribute were present, and had the value given by the default-validation attribute of the containing <xsl:stylesheet> element. If no default is specified, the effect is the same as «validation="strip" » .

XSLT does not provide any way of requesting validation of an attribute against a local attribute or type definition in a schema. The way around this is to request validation only when you create an element for which there is a top-level definition in the schema. This will then implicitly validate the whole subtree contained by that element, including elements and attributes that have local definitions in the schema.

Usage

You will sometimes see stylesheets that use the <xsl:attribute> instruction whenever they need to output an attribute value. However, in XSLT there are several different ways of generating an attribute in the result tree. This section compares the different approaches. It then looks specifically at the problem of creating an attribute whose value is a QName, such as an «xsi:type » attribute.

Different Ways of Creating Attributes

Where an output element is generated using a literal result element, the simplest way to specify attributes is normally to include them as attributes on the literal result element itself. You can do this even when the value is derived from information in the source document, because the value can be generated using an attribute value template, for example:

  <body bgcolor="#{@red}{@green}{@blue}">  

This concatenates three attributes of the current node in the source tree to create a single attribute in the result tree. Attribute value templates are described in Chapter 3, page 116.

Using <xsl:attribute> gives you more control than writing the attribute directly using attribute value templates. It is useful where one of the following conditions applies:

  • The parent element is output using <xsl:element> or <xsl:copy> (rather than a literal result element).

  • There is conditional logic to decide whether to output the attribute or not.

  • The name of the attribute is computed at runtime.

  • There is complex logic to calculate the value of the attribute.

  • The attribute is one of a set that can conveniently be grouped together using <xsl:attribute-set> .

  • The output attribute belongs to a namespace that is not present in the source document or the stylesheet.

A third way to output attributes is to copy them from the source tree to the result tree by using <xsl:copy> or <xsl:copy-of> . This works only if the attribute you want to generate has the same name and same value as an attribute in the source.

<xsl:copy> 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 <xsl:copy> , for example the following code ensures that the width , height , and depth attributes of the source < parcel > element are copied to the output <package> element, but its value and owner attributes are discarded:

  <xsl:template match="parcel">   <package>   <xsl:apply-templates select*"@*"/>   </package>   </xsl:template>   <xsl:template match="parcel/@width  parcel/@height  parcel/@depth">   <xsl:copy/>   </xsl:template>   <xsl:template match="parcel/@value    parcel/@owner"/>  

This example uses <xsl:apply-templates> to process all the attributes of the <parcel> 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 <xsl:copy-of> , as follows:

  <xsl:template match="parcel">   <package>   <xsl:copy-of select="@width, @height, @depth"/>   </package>   </xsl:template>  

The select expression here selects a sequence containing all the width , height , and depth attributes of the context node, and the <xsl:copy-of> instruction copies this sequence. The «, » operator, described in XPath 2.0 Programmer's Reference , 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 <xsl:copy-of select="@*"/> . If you want to copy all the attributes except certain particular ones, you can use the XPath 2.0 «except » operator:

  <xsl:copy-of select=@* except (@value, @owner)"/>  

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 <xsl:attribute-set> declaration, described on page 214.

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 <xsl:template> and <xsl:variable> , 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. Attributes containing XPath expressions obviously can't be declared as QNames, but less obviously, the schema for XSLT doesn't define the name attribute of <xsl:template> or <xsl:variable> as an xs:QName either. The reason for this is subtle: Although XML Schema would apply the right validation rules if they were declared as QNames, it would not follow the correct rules when converting the lexical value into a value in the QName value space. This is because the XML Schema definition of xs:QName (you'll need to look in the errata or the second edition to find it) says that an unprefixed QName is assumed to be in the default namespace, whereas the QNames used in these XSLT contexts never use the default namespace.

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 265.

  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 <xsl:namespace> instruction described on page 346.

So to generate the element <e xsi:type="xs:decimal">93.7</e> , write:

  <e>   <xsl:attribute name="xsi:type"   namespace="http://www.w3.org/2001/XMLSchema-instance"   select="'xs:decimal'">   <xsl:namespace name="xs"   select="'http://www.w3.org/2001/XMLSchema '"/>   <xsl:value-of select="93.7"/>   </e>  

An alternative to using <xsl:namespace> , 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:

  <e xmlns:xs="http://www.w3.org/2001/XMLSchema">   <xsl:attribute name= "xsi:type"   namespace="http://www.w3.org/2001/XJfcSehema-instance"   select="'xs:decimal'">   <xsl:value-of Select="93.7"/>   </e>  

The cases where <xsl:namespace> is needed are (a) where the element is produced using <xsl:element> 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 <e> element in the stylesheet is xs:decimal , and of course it isn't. You could avoid such problems by using namespace aliasing (see <xsl: namespace-alias > on page 350), but in my view generating the attribute using <xsl:attribute> is easier.

Examples

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

Generating an Attribute Conditionally
start example

This example shows the use of <xsl:attribute> 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 .

  <?xml version="    1    1.0"?>   <countries>   <country name="France"/>   <country name="Germany"/>   <country name="Israel"/>   <country name="Japan"/>   <country name="Poland"/>   <country name    =    "United States" selected="yes"/>   <country name="Venezuela"/>   </countries>  

Stylesheet

The stylesheet file is options.xsl .

This is a complete stylesheet using the simplified stylesheet syntax described in Chapter 3, page 119. 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.

  <html xsl:version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <body>   <h1>Please select a country:</h1>   <select id="country">   <xsl:for-each select="//country">   <option value="{@name}">   <xsl:if test="@selected='yes   '   ">   <xsl:attribute name="selected">selected</xsl:attribute>   </xsl:if>   <xsl:value-of select="@name"/>   </option>   </xsl:for-each>   </select>   <hr/>   </body>   </html>  

Output

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

click to expand
Figure 5-1
end example
 

The following example outputs a <promotion> element with either a code or reason-code attribute depending on the variable $schema-version . This kind of logic can be useful in an application that has to handle different versions of the output document schema.

Deciding the Attribute Name at Runtime
start example

This example shows the use of <xsl:attribute> in a situation where the name of the generated attribute is decided at runtime.

Source

This example works with any source file.

Stylesheet

The stylesheet can be found in the file conditional.xsl .

The stylesheet declares a global parameter «schema-version » , which controls the name of the attribute used in the output file.

  <xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <xsl:param name="schema-version" select="4.0"/>   <xsl:template match="/">   <promotion>   <xsl:variable name="attname"   select="if ($schema-version lt 3.0)   then 'code'   else 'reason-code'"/>   <xsl:attribute name="{$attname}" select="17"/>   </promotion>   </xsl:template>   </xsl:stylesheet>  

Output

With the default value of the parameter «schema-version » , the output is:

  <promotion reason-code="17"/>  

When run with the parameter «schema-version » set to 2.0, the output is:

  <promotion code="17"/>  
end example
 

In the above example it would be equally valid, of course, to use <xsl:attribute> with a fixed attribute name in both arms of the <xsl:choose> element; the advantage of doing this the way we have shown would start to become apparent if the sequence constructor of the <xsl:attribute> instruction were more complicated than the simple constant «17 » .

In XSLT 1.0, it was often necessary to use <xsl:attribute> because the value required a calculation. In the following example, the value of the value attribute is a whitespace-separated list of the id attributes of the child <item> elements of the context node:

  <basket>   <xsl:attribute name="value">   <xsl:for-each select="item">   <xsl:value-of select="@id"/>   <xsl:if test="not(position()=last())">   <xsl:text> </xsl:text>   </xsl:if>   </xsl:for-each>   </xsl:attribute>   </basket>  

In XSLT 2.0, the work can often be done at the XPath level. This example can now be written:

  <basket value="{item/@id}"/>  

because when the value of an expression in an attribute value template is given as a sequence, the processor will automatically convert the items in this sequence to strings and concatenate them using a single space as a separator.

See Also

  • <xsl:element> on page 260

  • <xsl:copy> on page 240

  • <xsl:copy-of> on page 245




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