0

I am exporting to pdf a table generated at run time in Oracle APEX, using XSL-FO for the report query template. Unfortunately, long words inside cells are not wrapped and they overlap the adjacent cell, making the report really ugly and useless. How can this be solved? NOTE: I am aware that this questions has already been asked many times. My problem is that none of the solutions I have found seems to work. In particular, I am implementing what I found here: XSL-FO: Force Wrap on Table Entries

With this solution, nothing is happening. I tried inserting a command for red text inside the template, to check if it was working, but the answer is no. You can see I tried using "hyphenate" and "wrap-option" too, as seen in other answers to the problem, but with no success. How can I fix this? Is the template for "intersperse-with-zero-spaces" put in the right position?

This is my code:

 <xsl:stylesheet xmlns:fox="http://xml.apache.org/fop/extensions" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://icl.com/saxon" extension-element-prefixes="saxon" >
    <xsl:variable name="_XDOFOPOS" select="''"/>
    <xsl:variable name="_XDOFOPOS2" select="number(1)"/>
    <xsl:variable name="_XDOFOTOTAL" select="number(1)"/>
    <xsl:variable name="_XDOFOOSTOTAL" select="number(0)"/>

    <!-- VARIOUS OTHER ATTRIBUTES HERE  -->

    <xsl:attribute-set name="cell">
        <xsl:attribute name="background-color">#BODY_BG_COLOR#</xsl:attribute>     
        <xsl:attribute name="color">#BODY_FONT_COLOR#</xsl:attribute>
        <xsl:attribute name="padding-start">5.15pt</xsl:attribute>
        <xsl:attribute name="vertical-align">top</xsl:attribute>
        <xsl:attribute name="padding-top">0.0pt</xsl:attribute>
        <xsl:attribute name="padding-end">5.15pt</xsl:attribute>
        <xsl:attribute name="number-columns-spanned">1</xsl:attribute>
        <xsl:attribute name="height">0.0pt</xsl:attribute>
        <xsl:attribute name="padding-bottom">0.0pt</xsl:attribute>
                <xsl:attribute name="font-style">italic</xsl:attribute>
                <xsl:attribute name="color">blue</xsl:attribute>
        <xsl:attribute name="hyphenate">true</xsl:attribute>
        <xsl:attribute name="wrap-option">wrap</xsl:attribute>
    </xsl:attribute-set>
    <xsl:attribute-set name="header-color">
        <xsl:attribute name="background-color">#HEADER_BG_COLOR#</xsl:attribute>
        <xsl:attribute name="color">#HEADER_FONT_COLOR#</xsl:attribute>
    </xsl:attribute-set>


    <!-- Trying this to wrap long words   -->

    <xsl:template match="text()">    
        <xsl:call-template name="intersperse-with-zero-spaces">
            <xsl:with-param name="str" select="."/>
                <xsl:attribute name="color">red</xsl:attribute>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="intersperse-with-zero-spaces">
        <xsl:param name="str"/>
        <xsl:variable name="spacechars">
            &#x9;&#xA;
            &#x2000;&#x2001;&#x2002;&#x2003;&#x2004;&#x2005;
            &#x2006;&#x2007;&#x2008;&#x2009;&#x200A;&#x200B;
        </xsl:variable>

        <xsl:if test="string-length($str) &gt; 0">
            <xsl:variable name="c1" select="substring($str, 1, 1)"/>
            <xsl:variable name="c2" select="substring($str, 2, 1)"/>

            <xsl:value-of select="$c1"/>
            <xsl:if test="$c2 != '' and
                    not(contains($spacechars, $c1) or
                    contains($spacechars, $c2))">
                <xsl:text>&#x200B;</xsl:text>
            </xsl:if>

            <xsl:call-template name="intersperse-with-zero-spaces">
                <xsl:with-param name="str" select="substring($str, 2)"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>  
    <!-- long word wrap end  -->


    <xsl:template match="DOCUMENT"> 
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
        <!-- OTHER STUFF AND THE TABLE ... -->                      

        </fo:root>
    </xsl:template>

</xsl:stylesheet>
Discipulus
  • 245
  • 1
  • 3
  • 13
  • Your `red` is completely out of place. I would be surprised if the transformation worked at all. `xsl:attribute` is not allowed as a child of `xsl:call-template` (see https://www.w3.org/TR/1999/REC-xslt-19991116#section-Defining-Template-Rules). Even if it was allowed at that point, you are creating text nodes, and text nodes don't have attributes. – Tony Graham Apr 29 '20 at 13:05

1 Answers1

1

To see if the template is used, change:

<xsl:value-of select="$c1"/>

to:

<fo:inline color="red"><xsl:value-of select="$c1"/></fo:inline>

To see the template's effect, change &#x200B; in <xsl:text>&#x200B;</xsl:text> to a printing character, e.g., .. You'll get even more overflowing table cells, but you'll know why.

Tony Graham
  • 7,306
  • 13
  • 20
  • thanks for your reply. No, it doesn't work. It just keeps printing the table as before. It seems like the template is not applying to the content of the table, nor any other text in the report. – Discipulus Apr 29 '20 at 13:27
  • Is the `` that you show in a stylesheet module that is imported by another module? Is there another template that matches on `text()` either in the current module or in a module that imports the current module? If so, that template will be overriding the template that you show. – Tony Graham Apr 29 '20 at 13:32
  • The XSL-FO used by APEX is basically the one that I am showing, with just a couple of other fo:table-cells elements and a fo:table-column defined after the end of the stylesheet. So i guess there are no other modules importing the stylesheet. Also, there are no other templates matching with "text()". I am rather new to both Oracle APEX and XSL_FO, so I hope to be answering correctly to your questions. – Discipulus Apr 29 '20 at 16:59
  • I don't know Oracle APEX either, so we're well matched. Is there a template for a table cell that uses `xsl:value-of` to get the string value of the cell contents? If so, change the `xsl:value-of` to an `xsl:apply-templates` so that your template for `text()` is used. – Tony Graham Apr 30 '20 at 07:13
  • @Toni Graham, yes, now it works, thank you! – Discipulus Apr 30 '20 at 13:42