xsltxsl-fo

Applying attributes to fo:block based on certain conditions


I'm trying to construct a xsl:function, xsl:template or anything that will bring me the correct solution for the following.

I've got a XSL:FO with a lot of <fo:block> elements which need to contain all kinds of attributes to style the text in that element (eg. font-size, letter-spacing etc...). I want to reduce the redundancy of adding all those attributes inline in the elements. I already improved this by adding all those attributes to the elements and making their value be set from a variable (eg. <fo:block font-size="{$titlefontsize" />).

Though, I'd like to take it one step further, ideally, I'd like something like this, which obviously does not work:

<fo:block my:applyFontStyle('h2') margin-left="10mm">...</fo:block>

Please note, that I still need to be able to apply attributes which apply to the same element.


Solution

  • Look at using named attribute sets (see https://www.w3.org/TR/xslt-30/#attribute-sets).

    You can do things like:

    <xsl:attribute-set name="heading">
      <xsl:attribute name="font-weight">bold</xsl:attribute>
    </xsl:attribute-set>
    
    <xsl:attribute-set name="h2" use-attribute-sets="heading">
      <xsl:attribute name="font-size" select="'1.5em'" />
    <xsl:attribute-set>
    
    <xsl:template match="heading2">
      <fo:block xsl:use-attribute-sets="h2" margin-left="10mm">
    ...
    

    The xsl:attribute in an xsl:attribute-set are evaluated each time, so you can do things like:

    <xsl:attribute-set name="id">
      <xsl:attribute name="id" select="generate-id()" />
    </xsl:attribute-set>