[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: The use of a variable in use-attribute-sets attrib

Subject: Re: The use of a variable in use-attribute-sets attribute
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Tue, 15 May 2001 19:00:24 +0100
xsl use attribute sets variable
Hi Joshua,

Just a couple of insights that might help you get to a more concise
solution.  First, all those xsl:element elements can be created with
literal result elements instead:

<xsl:template match="td">
   <fo:table-cell>
      <xsl:apply-templates select="@class"/>
      <fo:block>
         <xsl:apply-templates />
      </fo:block>
   </fo:table-cell>
</xsl:template>

Second, in the @class-matching template, since you're creating the
same attributes each time, just with different values, then you could
do the xsl:choose within each of the xsl:attribute elements instead of
the other way round.

<xsl:template match="@class">
   <xsl:attribute name="font-size">
      <xsl:choose>
         <xsl:when test=". = 'classname1'">12pt</xsl:when>
         <xsl:when test=". = 'classname2'">14pt</xsl:when>
         <xsl:when test=". = 'classname3'">16pt</xsl:when>
      </xsl:choose>
   </xsl:attribute>
   <xsl:attribute name="font-weight">
      <xsl:choose>
         <xsl:when test="@class = 'classname3'">normal</xsl:when>
         <xsl:otherwise>bold</xsl:otherwise>
      </xsl:choose>
   </xsl:attribute>
</xsl:template>

Now, one thing about attribute sets is that they *can* include
attributes whose values are calculated on the fly, based on the
current node.  So rather than having this separate template to create
the attributes, you could have an attribute set that does the same
thing, based on the @class attribute of the current node:

<xsl:attribute-set name="td-font">
   <xsl:attribute name="font-size">
      <xsl:choose>
         <xsl:when test="@class = 'classname1'">12pt</xsl:when>
         <xsl:when test="@class = 'classname2'">14pt</xsl:when>
         <xsl:when test="@class = 'classname3'">16pt</xsl:when>
      </xsl:choose>
   </xsl:attribute>
   <xsl:attribute name="font-weight">
      <xsl:choose>
         <xsl:when test="@class = 'classname3'">normal</xsl:when>
         <xsl:otherwise>bold</xsl:otherwise>
      </xsl:choose>
   </xsl:attribute>
</xsl:attribute-set>

Then you could just use the attribute set in the normal way:

<xsl:template match="td">
   <fo:table-cell xsl:use-attribute-sets="td-font">
      <fo:block>
         <xsl:apply-templates />
      </fo:block>
   </fo:table-cell>
</xsl:template>

So, that's fine if you want to create the same attributes all the
time - you can change their values based on the class name.

Another thing you could do is create separate attribute sets, but
rather than use them with xsl:use-attribute-sets, access them
programmatically, using them to define the attributes that you want to
add.  So you could define the separate attribute sets:

<xsl:attribute-set name="classname1">
   <xsl:attribute name="font-size">12pt</xsl:attribute>
   <xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:attribute-set>

<xsl:attribute-set name="classname2">
   <xsl:attribute name="font-size">14pt</xsl:attribute>
   <xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:attribute-set>

<xsl:attribute-set name="classname3">
   <xsl:attribute name="font-size">16pt</xsl:attribute>
   <xsl:attribute name="font-weight">normal</xsl:attribute>
</xsl:attribute-set>

You can then access these using the document() function to access the
current stylesheet as a node tree, and then apply templates to the
relevant attribute set according to the class name:

<xsl:template match="td">
   <xsl:variable name="class" select="@class" />
   <fo:table-cell>
      <xsl:apply-templates
         select="document('')/*/xsl:attribute-set[@name = $class]" />
      <fo:block>
         <xsl:apply-templates />
      </fo:block>
   </fo:table-cell>
</xsl:template>

Then have a template that matches an attribute set and goes through
each of the xsl:attribute elements within it to add the relevant
attributes:

<xsl:template match="xsl:attribute-set">
   <xsl:for-each select="xsl:attribute">
      <xsl:attribute name="{@name}">
         <xsl:value-of select="." />
      </xsl:attribute>
   </xsl:for-each>
</xsl:template>

Once you make *that* realisation, it becomes clear that you *could*
define the attributes to be generated for particular classes within
its own XML structure, elsewhere.  You might find it more convenient
to do something like:

<classes>
   <class name="classname1" font-size="12pt" font-weight="bold" />
   <class name="classname2" font-size="14pt" font-weight="bold" />
   <class name="classname3" font-size="16pt" font-weight="normal" />
</classes>

Assuming that $classes holds a node set containing those class
elements (you might access them from a separate document using the
document() function, for example), then with this syntax you could
just *copy* the relevant attributes onto the fo:table-cell:

<xsl:template match="td">
   <xsl:variable name="class" select="@class" />
   <fo:table-cell>
      <xsl:copy-of select="$classes[@name = $class]" />
      <fo:block>
         <xsl:apply-templates />
      </fo:block>
   </fo:table-cell>
</xsl:template>

This type of approach is good if you have fixed *values* for the
various attributes, but might change *which* attributes should be
added for particular classes.

Anyway, sorry for the (characteristically) long mail, but I just
wanted to show some alternative ways of approaching the problem.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.