xmlxsltxslt-2.0xsl-foapache-fop

Add a blank space when an empty tag in XML is encountered


Im using Apache FOP to create PDFs.

Part of my XML looks like below. Basically i am trying to put the entire content of the tags as is in the PDF and I'm having a bit of challenge here. I would like to have an blank space when there is an empty TEXT tag:

"<Text></Text>"

XML:

    <Text>NUMBER             :   123456      ABCDE     -  ASBI</Text>
    <Text>REFERENCENUMBER    : TECNO - ENOS-B</Text>
    <Text></Text>
    <Text>USER   1           : COMPANY XYZ</Text>
    <Text>                     TECH CENTER1</Text>
    <Text>                     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXX X XX</Text>
    <Text>                     0000 XXXXXXXXXXXXXXXXXXXX</Text>
    <Text>USER   2           : COMPANY MNO</Text>
    <Text>                     TECH CENTER2</Text>
    <Text>                     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXX X XX</Text>
    <Text>                     0000 XXXXXXXXXXXXXXXXXXXX</Text>
    <Text></Text>
    <Text>QTY. SUBSCRIPTION PRICE, OPTICAL CAPACITY</Text>

My code consists of a for-each block on the node Text:

                            <xsl:for-each select="Text">
                            <fo:table-row>
                                <fo:table-cell>
                                    <fo:block font-family="Courier" font-size="7pt" font-weight="normal" display-align="center" white-space="pre">
                                        <xsl:value-of select="."/>
                                    </fo:block>
                                </fo:table-cell>
                            </fo:table-row>
                        </xsl:for-each>

Im able to achieve the blank spaces in the tag using the White-space="pre". But how do i get a blank line? My output looks like below:

    NUMBER             :   123456      ABCDE     -  ASBI
    REFERENCENUMBER    : TECNO - ENOS-B 
    USER   1           : COMPANY XYZ
                           TECH CENTER1
                         XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXX X XX
                         0000 XXXXXXXXXXXXXXXXXXXX
    USER   2           : COMPANY MNO
                         TECH CENTER2
                         XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXX X XX
                         0000 XXXXXXXXXXXXXXXXXXXX
    QTY. SUBSCRIPTION PRICE, OPTICAL CAPACITY

Expected output :

    NUMBER             :   123456      ABCDE     -  ASBI
    REFERENCENUMBER    : TECNO - ENOS-B 

    USER   1           : COMPANY XYZ
                           TECH CENTER1
                         XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXX X XX
                         0000 XXXXXXXXXXXXXXXXXXXX
    USER   2           : COMPANY MNO
                         TECH CENTER2
                         XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXX X XX
                         0000 XXXXXXXXXXXXXXXXXXXX

    QTY. SUBSCRIPTION PRICE, OPTICAL CAPACITY

Solution

  • Your white-space="pre" shorthand also preserves linefeeds, as it also sets linefeed-treatment="preserve". (See https://www.w3.org/TR/xsl11/#white-space and https://www.w3.org/TR/xsl11/#linefeed-treatment)

    So you can put all of your Text in one fo:block and generate a linefeed after the string value of each Text:

    <xsl:template match="Block">
      <fo:block font-family="Courier" font-size="7pt" white-space="pre">
        <xsl:apply-templates select="Text" />
      </fo:block>
    </xsl:template>
    
    <xsl:template match="Text">
      <xsl:value-of select="." />
      <xsl:text>&#xA;</xsl:text>
    </xsl:template>
    

    The empty Text generate only a linefeed.

    You didn't show what goes around your Text, so I made up a Block element.