Subject: RE: [xsl] how to make data fit in a table cell in xsl-fo? From: "Andrew Welch" <awelch@xxxxxxxxxxxxxxx> Date: Thu, 17 Jan 2002 13:31:13 -0000 |
Somebody had a similar problem a while back (breaking large strings to fit in <td>'s). This is the xslt I used in that case that wraps a string (by inserting <br/>) at ever 30th char. To modify it for your needs, replace <br/> with ​ and change 30 to the position you want to insert at. I hope its useful! //put this template in between your <td> and </td> //remember to change $yourTextString (!) <xsl:call-template name="text_wrapper"> <xsl:with-param name="Text" select="$yourTextString"/> </xsl:call-template> //this will display the first 30 chars of $Text then pass the rest to wrapper_helper //if no string is left it will stop <xsl:template name="text_wrapper"> <xsl:param name="Text"/> <xsl:choose> <xsl:when test="string-length($Text)"> <xsl:value-of select="substring($Text,1,30)"/><br/> <xsl:call-template name="wrapper_helper"> <xsl:with-param name="Text" select="substring($Text,31)"/> </xsl:call-template> </xsl:when> <xsl:otherwise> no more string! </xsl:otherwise> </xsl:choose> </xsl:template> //this will also display 30 chars of the string, and pass the rest back to text_wrapper <xsl:template name="wrapper_helper"> <xsl:param name="Text"/> <xsl:value-of select="substring($Text,1,30)"/><br/> <xsl:call-template name="text_wrapper"> <xsl:with-param name="Text" select="substring($Text,31)"/> </xsl:call-template> </xsl:template> Cheers andrew === -----Original Message----- From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx]On Behalf Of Joerg Pietschmann Sent: Thursday, January 17, 2002 12:09 PM To: XSL List Subject: Re: [xsl] how to make data fit in a table cell in xsl-fo? yan bai <bytj@xxxxxxxxx> wrote: > The table has 7 columns. One of the columns may > contain a string like > "ABCD_XXX_YYY_D1_ZZZ_DDD_DD0_DA0". This column will > expand into the next column "col_2" and make the data > in the "col_2" column ineligible. That's quite obvious. What i'd like to know is what you want to have instead. I'll use the following FO snippet as example: <fo:table> <fo:table-column column-width="20mm"/> <fo:table-column column-width="20mm"/> <fo:table-body> <fo:table-row> <fo:table-cell> <fo:block>ABCD_XXX_YYY_D1_ZZZ_DDD_DD0_DA0</fo:block> </fo:table-cell> <fo:table-cell> <fo:block>test</fo:block> </fo:table-cell> </fo:table-row> </fo:table-body> </fo:table> For solutions at the FO-level, you can try hyphenation: <fo:block hyphenate="true" language="en">ABCD_XXX_YYY_D1_ZZZ_DDD_DD0_DA0</fo:block> This works somehow. FOP (0.20.2) will spout some errors ([ERROR]: >) which indicate repeated area overflow, you can ignore them. You might want to customize the hyphenation further, look at the http://www.w3.org/TR/xsl/slice7.html#common-hyphenation-properties for possibilities. Of course, hyphenation works best if the long words are really words. If they are artificial constructs as your example suggests (sort of product ids or something similar), hyphenation might not be what you want. The other solution, having long strings clipped at the cell boundary, apparently is not possible with FOP as it requires not yet implemented features. There are also some possible solutions at the XSLT level, in case you generate the FO this way. - You could insert a zero width space (​) into long strings, for example by replacing "_" by "_​". The FO processor is able to wrap the string at the zero width spaces if needed, and the spaces go unnoticed where no wrap is necessary. This gives you some control where the string can be wrapped but will of course fail if long substrings without an inserted zero width space remain. Unfortunately, this sort of replacement is not all that easy to do in XSLT, look at http://www.dpawson.co.uk/xsl/sect2/replace.html#d187e57 or the archives of this list for some hints. You might want to combine this with a tokenizer in order to process only long words, here http://www.dpawson.co.uk/xsl/sect2/N1755.html#d96e102 might get you started (use spaces instead of commas, of course). Alternatives are to insert a zero width space after each character, or after each N characters, where N characters can be expected to fit into the cell. - You could simply cut off long strings after N characters. Use a tokenizer to get the words in your text and use substring() on them. - Format the text yourself in order to ensure lines are no longer than N characters, either clipping or wrapping long strings in the process. You'll have to build a recursive template solution along the lines of the string replace mentioned above. I'm sure the list archive already contains code which could be reused. Be aware that the possible solutions which include "N character" may result in somewhat unpleasant appearance if you use a proportional font, as N has to be a preset constant. If you are after calculating column withs in order to fit the data into the cells, well, this can't currently be done in FO. For a solution at the XSLT level, you may use a tokenizer as mentioned above to get the words in the texts and try to derive the necessary column width from the string length of the words. In case you use proportional fonts you'll run into the same difficulties as in some of the possibilities mentioned above because you'll need font metrics for exact calculations, and there is no easy way in XSLT to retrieve them. Now: What do you actually mean by "fit data into a table cell"? HTH J.Pietschmann XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] how to make data fit in a, Joerg Pietschmann | Thread | Re: [xsl] how to make data fit in a, yan bai |
Re: [xsl] XSLT match with regex wha, Thomas Winkler | Date | [xsl] Looking for an XSD-validator , Rene de Vries |
Month |