XSL-FO 两列 table
XSL-FO two column table
我需要创建一个 2 列 table,由不固定数量的图像填充,每个单元格一个图像,每行两个单元格。我们正在使用 XSL-FO
我将此 XSL 数据作为 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>
你可以注意到标签 views
的内容是 base64 信息,编码 images.I 只是截断了它们;他们很长。
为了渲染图像,我使用标签 fo:external-graphic
。所以,我设法在单个 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>
如你所见;这是无效的;因为它是每个单元格的图像...关于如何将它们放在 2 列中的任何想法?
实现此目的的一种方法是最初 select 只有 views
元素将成为每行中的第一个单元格。
<xsl:for-each select="viewList/views[position() mod $cellsPerRow = 1]">
(其中 cellsPerRow 是一个设置为 2 的变量,这样您就可以轻松更改每行的单元格数)。这将构成您 fo:table-row
)
的基础
然后,对于 select 实际构成该行的单元格,您可以这样做
<xsl:for-each select="self::*|following-sibling::views[position() < $cellsPerRow]" >
试试这个 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() < $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>
请注意,我已经从使用 xsl:for-each
切换到 xsl:apply-templates
主要是为了避免在答案中过度缩进。
我需要创建一个 2 列 table,由不固定数量的图像填充,每个单元格一个图像,每行两个单元格。我们正在使用 XSL-FO
我将此 XSL 数据作为 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>
你可以注意到标签 views
的内容是 base64 信息,编码 images.I 只是截断了它们;他们很长。
为了渲染图像,我使用标签 fo:external-graphic
。所以,我设法在单个 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>
如你所见;这是无效的;因为它是每个单元格的图像...关于如何将它们放在 2 列中的任何想法?
实现此目的的一种方法是最初 select 只有 views
元素将成为每行中的第一个单元格。
<xsl:for-each select="viewList/views[position() mod $cellsPerRow = 1]">
(其中 cellsPerRow 是一个设置为 2 的变量,这样您就可以轻松更改每行的单元格数)。这将构成您 fo:table-row
)
然后,对于 select 实际构成该行的单元格,您可以这样做
<xsl:for-each select="self::*|following-sibling::views[position() < $cellsPerRow]" >
试试这个 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() < $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>
请注意,我已经从使用 xsl:for-each
切换到 xsl:apply-templates
主要是为了避免在答案中过度缩进。