Sometimes when you create a new element, you want to add a number of attributes to that element all at once. Theres an easy way to do that, because you can use the <xsl:attribute-set> element. This element has two attributes:
name (mandatory). The name of the attribute set. Set to a QName.
use-attribute-sets (optional). The names of other attribute sets you want included in this one. Set to a whitespace-separated list of QNames.
The <xsl:attribute-set> element encloses <xsl:attribute> elements, one for each new attribute you want to create. When you use <xsl:attribute-set> to create a new set of attributes for an element, you give the attribute set a name. You can then assign that name to the use-attribute-sets attribute of the <xsl:copy> , <xsl:element> , <xsl:for-each> elementsand of even the <xsl:attribute-set> element itselfto use that attribute set when you create the new element.
You already saw one example that used attribute sets in the JavaScript-creating template earlier in this chapter. In that example, I used an attribute set to specify all the attributes in the planets HTML buttons , then used that attribute set in an <xsl:element> element to create those buttons:
<BODY> <CENTER> <H1>The Mass Page</H1> </CENTER> <xsl:for-each select="PLANET"> <P/> <xsl:element name="input" use--attribute-sets="attribs"/> </xsl:for-each> <P/> <P/> <DIV ID='display'></DIV> </BODY> </HTML> </xsl:template> <xsl:attribute-set name="attribs"> <xsl:attribute name="type">BUTTON</xsl:attribute> <xsl:attribute name="value"><xsl:value-of select="NAME"/></xsl:attribute> <xsl:attribute name="onclick"><xsl:value-of select="NAME"/>()</xsl:attribute> </xsl:attribute-set>
In the result document, this attribute set was added to every HTML button, like this:
<P></P> <input type="BUTTON" value="Mercury" onclick="Mercury()"> <P></P> <input type="BUTTON" value="Venus" onclick="Venus()"> <P></P> <input type="BUTTON" value="Earth" onclick="Earth()">
In the following example, I use an attribute set to number the planets in planets.xml. I add two attributes to each <PLANET> element: number and total . The number attribute will hold the planets number, starting from 1, and the total attribute will hold the total number of planets in planets.xml, which I can determine with the count function (which youll see in Chapter 8):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes"/> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="PLANET"> <xsl:copy use-attribute-sets="numbering"> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:attribute-set name="numbering"> <xsl:attribute name="number"><xsl:number/></xsl:attribute> <xsl:attribute name="total"><xsl:value-of select="count(//PLANET)"/></xsl:attribute> </xsl:attribute-set> </xsl:stylesheet>
Heres the result. Note that every <PLANET> element has both a number and total attribute:
<?xml version="1.0" encoding="UTF-8"?> <PLANETS> <PLANET number="1" total="3"> <NAME>Mercury</NAME> <MASS>.0553</MASS> <DAY>58.65</DAY> <RADIUS>1516</RADIUS> <DENSITY>.983</DENSITY> <DISTANCE>43.4</DISTANCE> </PLANET> <PLANET number="2" total="3"> <NAME>Venus</NAME> <MASS>.815</MASS> <DAY>116.75</DAY> <RADIUS>3716</RADIUS> <DENSITY>.943</DENSITY> <DISTANCE>66.8</DISTANCE> </PLANET> <PLANET number="3" total="3"> <NAME>Earth</NAME> <MASS>1</MASS> <DAY>1</DAY> <RADIUS>2107</RADIUS> <DENSITY>1</DENSITY> <DISTANCE>128.4</DISTANCE> </PLANET> </PLANETS>