[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
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
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|