More Element and Attribute Manipulation - Page 7
November 2, 2001
In our first stylesheet, we saw that an xsl:apply-
templates element with no attributes tells the XSLT
processor to apply any relevant templates to all the matched
node's children. By using this element type's select
attribute, you can be pickier about exactly which children of a
node should be processed and in what order.
For example, this stylesheet
<!-- xq25.xsl: converts xq26.xml into xq27.xml -->
<xsl:template match="wine">
<wine>
<price><xsl:apply-templates select="price"/></price>
<product><xsl:apply-templates select="product"/></product>
</wine>
</xsl:template>
will turn this XML element
<wine grape="chardonnay">
<product>Carneros</product>
<year>1997</year>
<price>10.99</price>
</wine>
into this:
<wine>
<price>10.99</price>
<product>Carneros</product>
</wine>
The stylesheet performs two important operations on this element:
- It moves the price element before the product element.
- It deletes the year element.
The first technique that we saw for deleting an element—using an
empty template for that element type — is often simpler
than adding xsl:apply-templates elements for each of an element's
children (except the ones you want to delete). If you're
reordering the children anyway, as with the preceding example,
omitting an xsl:apply-templates element for the
elements in question can be an easier way to delete them.
Manipulating attributes
We've seen how to delete and rename elements. How do you delete
and rename attributes? For example, how would you delete the
following wine element's price
attribute and rename its year attribute to
vintage?
<wine price="10.99" year="1997">Carneros</wine>
We want the result to look like this:
<wine vintage="1997">Carneros</wine>
(Because an XML declaration is optional, it won't make any
difference if that shows up as well.) The first template rule in
the following stylesheet makes both of these changes:
<!-- xq30.xsl: converts xq28.xml into xq29.xml -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="wine">
<wine vintage="{@year}"> <!-- price attribute omitted -->
<xsl:apply-templates/>
</wine>
</xsl:template>
<!-- Copy all the other source tree nodes. -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates
select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Deleting the price attribute was easy: the template
just left the attribute out of the wine start-tag in
the template. To rename the year attribute to
vintage, the year start-tag includes
the attribute specification vintage="{@year}". The
part between the quotation marks says "put the value of the
source tree wine element's year
attribute here." The @ character is shorthand for the XPath
notation that means "get the value of the attribute with this
name," and the curly braces tell the XSLT processor that the
expression they contain is an attribute value template — not a
literal string to appear in the result tree exactly as shown, but
an expression to be eval-uated and replaced with the result of
the evaluation. If this attribute specification had said
vintage="{2+2}", the XSLT processor would have added
vintage="4" to the result tree. In the example, the
processor understands the meaning of @ and plugs in the
appropriate attribute value between the quotation marks on the
result tree.
Running an XSLT processor - Page 6
XSLT Quickly
Attribute Value Templates - Page 8
|