简体   繁体   中英

XSL-FO two column table

I need to create a 2 column table, filled by a not-fixed number images, one image per cell, two cell per row. We are using XSL-FO

I have this XSL data as input for XSL

<viewList>
    <views order="1">data:image/jpg;base64,/9j/4AAQSkZJRg...(base64 data)</views>
    <views order="2">data:image/jpg;base64,/9j/4AAQSkZ432...(base64 data)</views>
    <views order="3">data:image/jpg;base64,/9j/4AAQSkZdgd...(base64 data)</views>
    <views order="4">data:image/jpg;base64,/9j/4AAQSkZ775...(base64 data)</views>
    <views order="5">data:image/jpg;base64,/9j/4AAQSk7655...(base64 data)</views>
</viewList>

As you can notice content of tag views are base64 info, coding images.I have just truncate them; they are quite long.

For rendering images I use tag fo:external-graphic . So, I manage to paint all images in a single table:

<fo:table>
<fo:table-body>   
    <xsl:for-each select="viewList/views">                                      
        <fo:table-row>
            <fo:table-cell>                                        
                <fo:block text-align="center">
                    <fo:external-graphic src="{current()}"/>
                </fo:block>                    
            </fo:table-cell>
        </fo:table-row>
    </xsl:for-each>
</fo:table-body>  
</fo:table>

As you see; this is not enterely valid; bacause its an image per cell... any idea on how to put them in 2 columns?

One way to achieve this is to initially select only the views element that will become the first cell in each row.

 <xsl:for-each select="viewList/views[position() mod $cellsPerRow = 1]">

(Where cellsPerRow is a variable set to 2, which would then allow you easily to change the number of cells per row). This would then form the basis of your fo:table-row )

Then, to select the cells that actually form the the row, you would do this

<xsl:for-each select="self::*|following-sibling::views[position() &lt; $cellsPerRow]" >

Try this XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="fo" version="2.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:param name="cellsPerRow" select="2" />
    <xsl:template match="/">
        <fo:table>
            <fo:table-body>   
                <xsl:for-each select="viewList/views[position() mod $cellsPerRow = 1]">                                      
                    <fo:table-row>
                        <xsl:apply-templates select="self::*|following-sibling::views[position() &lt; $cellsPerRow]" />
                    </fo:table-row>
                </xsl:for-each>
            </fo:table-body>  
        </fo:table>
    </xsl:template>

    <xsl:template match="views">
        <fo:table-cell>                                        
            <fo:block text-align="center">
                <fo:external-graphic src="{current()}"/>
            </fo:block>                    
        </fo:table-cell>
    </xsl:template>
</xsl:stylesheet>

Note, I've switched from using xsl:for-each to xsl:apply-templates mainly to avoid excessive indentation in the answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM