5. Adding named styles support to an existing XSLT stylesheet

Retrofitting named styles support in an existing XSLT stylesheet which has been designed to generate XSL-FO for use by Apache FOP, RenderX XEP or Antenna House XSL Formatter (or XFC, but without named styles) is tedious and error prone. We strongly recommend to avoid doing this.

However, it's not difficult to design from scratch an XSLT stylesheet which generates XSL-FO making using of named styles and which works equally well when used in conjunction with XSL-FO processors other than XFC.

The key ideas allowing to do this are:

  1. An extension attribute such as xfc:user-style should be ignored by XSL-FO processors other than XFC.

  2. Specifying the same XSL-FO attributes twice —one time inside the named style for use by XFC and a second time directly on the XSL-FO element for use by the other XSL-FO processors— will not predate the possibility for the user of the word processor to later modify the aspect of the generated document by editing the named styles.

    This works fine because as explained in Section 2.2, “The effect of the xfc:user-style extension attribute on an XSL-FO element”, XFC ignores redundant attributes, that is, XSL-FO attributes specified at the same time inside the named style and also directly on the XSL-FO element.

A sample XSLT stylesheet is found in sample1.xsl:

...
<xsl:attribute-set name="plain">
  <xsl:attribute name="font-family">serif</xsl:attribute>
  <xsl:attribute name="font-size">10pt</xsl:attribute>
  <xsl:attribute name="line-height">1.3em</xsl:attribute>
</xsl:attribute-set>
...

<xsl:attribute-set name="p" use-attribute-sets="plain">
  <xsl:attribute name="text-align">justify</xsl:attribute>
  <xsl:attribute name="space-before">1.3em</xsl:attribute>
  <xsl:attribute name="space-after">1.3em</xsl:attribute>
</xsl:attribute-set>

<xsl:template match="h:p">
  <fo:block xsl:use-attribute-sets="p">1
    <xsl:if test="$use-styles = 'yes'">
      <xsl:attribute name="xfc:user-style">Paragraph</xsl:attribute>2
    </xsl:if>

    <xsl:apply-templates />
  </fo:block>
</xsl:template>

1

This fo:block element has a number of XSL-FO attributes directly set on it by the means of xsl:attribute-set "p".

2

The very same XSL-FO attributes are found in the "Paragraph" paragraph-style. Excerpts from sample1.xfc:

<paragraph-style name="Paragraph" text-align="justify"
                 font-size="10pt" line-height="1.3em"
                 space-before="1.3em" space-after="1.3em" />

Run for example Saxon 6, to generate an XSL-FO file, sample1.fo, for use by XSL-FO processors other than XFC:

java -jar saxon.jar -o sample1.fo sample1.xhtml sample1.xsl

After doing that, convert sample1.fo to PDF for example using Apache FOP:

fop -r -q -fo sample1.fo -pdf sample1.pdf

Run for example Saxon 6, to generate an XSL-FO file, sample1_sty.fo, for use by XFC:

java -jar saxon.jar -o sample1_sty.fo sample1.xhtml sample1.xsl use-styles=yes

After doing that, convert sample1.fo to sample1.docx for example:

fo2docx /sty sample1.xfc sample1_sty.fo sample1.docx