Search code examples
xsltxsl-fo

How to insert a blank line in XSL-FO properly?


I am trying to figure out how to do that properly. I tried to use processing instructions in the code but it seems they are somehow ignored at all.

In the text:

end of a paragraph.<?linebreak?></p>

As for templating, I tried:

<xsl:template match="processing-instruction('linebreak')">
    <fo:block>
        <xsl:apply-templates/>
        <fo:leader/>
    </fo:block>
</xsl:template>

Or simply for testing purposes:

<xsl:template match="processing-instruction('linebreak')">
    <fo:block>XXXX</fo:block>
</xsl:template>

No matters what I do, the template is never used.

I use it inside an eXist-db app (3.0RC1) but I think this is not associated with eXist-db. There is FOP 1.1. I am not sure about the Saxon version.


Solution

  • No matters what I do, the template is never used.

    Concerning this part of the problem, a possible explanation is that the template matching the parent element (<p> in your examples) silently ignores processing instructions when applying templates.

    For example, this quasi-identity stylesheet ignores processing instructions when elements are processed, so their matching template is never executed:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
      <xsl:template match="* | @*">
        <xsl:copy>
          <!-- this only processes elements, attributes and text nodes! -->
          <xsl:apply-templates select="* | @* | text()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="processing-instruction('linebreak')">
        XXXXX
      </xsl:template>
    
    </xsl:stylesheet>
    

    In order for the processing instructions to be taken into account, the template matching elements must explicitly apply templates to them too:

      <xsl:template match="* | @*">
        <xsl:copy>
          <xsl:apply-templates select="* | @* | text() | processing-instruction()"/>
        </xsl:copy>
      </xsl:template>
    

    Note that using <xsl:apply-templates/> would not work too, as it does not select processing instructions nor attributes, just elements and text nodes.