Search code examples
xmlxsltxsl-foapache-fop

how to insert a blank line without affecting the order in XSL-FO


The XML contains multiple PrintSections and they have multiple Text and Barcode sections. I need to output a blank line after the first PrintSection (or at least every PrintSection) without changing the order in which they are present in the XML.

XML

<Document>
    <PrintSection>
        <Text/>
        <Text/>
    </PrintSection>
    <PrintSection>
        <Text/>
        <Barcode/>
    </PrintSection>
    <PrintSection>
        <Text/>
        <Text/>
    </PrintSection>
</Document>

XSL

<xsl:template match="/">
.....
</xsl:template>

<xsl:template match="Text">
    <fo:block>
        <xsl:apply-templates select="Text1" />
    </fo:block>
</xsl:template>

<xsl:template match="Barcode">
    <fo:block>
        <xsl:apply-templates select="Barcode1" />
    </fo:block>
</xsl:template>

I tried adding this

<xsl:template match="PrintSection">
    <fo:block>
        <xsl:apply-templates select="Text" />
        <xsl:apply-templates select="Barcode" />
        <fo:leader/>
    </fo:block>
</xsl:template>

This inserts a blank line but it prints the Barcode at the very end changing the natural order.


Solution

  • Add a space-before property (https://www.w3.org/TR/xsl11/#space-before) on all PrintSection except the first:

    <fo:template match="Document">
      <xsl:apply-templates select="PrintSection" />
    </fo:template>
    
    <fo:template match="PrintSection">
       <fo:block>
        <xsl:if test="position() > 1">
          <xsl:attribute name="space-before">1.4em</xsl:attribute>
        </xsl:attribute>
        <xsl:apply-templates />
      </fo:block>
    </xsl:template>
    

    The template for Document is there just to show that all the PrintSection should be selected in one go so the position() in the test works as expected. If it wasn't for the white-space text nodes between your PrintSection in your sample, that's what would happen anyway and the template shown for Document would be redundant.