[英]XSLT & XSL-FO: Creating a table with multiple rows?
我对XSLT还是很陌生,并且遇到一个问题,即我有一个子元素数量未知的Element,我需要在表中显示这些子元素,以便有5-6列可用于显示信息。
如果给我一个看起来像这样的XML文件:
<books>
<book>
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
</book>
<book>
<author>Corets, Eva</author>
<title>Maeve Ascendant</title>
</book>
<book>
<author>Corets, Eva</author>
<title>Oberon's Legacy</title>
</book>
<book>
<author>Randall, Cynthia</author>
<title>Lover Birds</title>
</book>
<book>
<author>Thurman, Paula</author>
<title>Splish Splash</title>
</book>
<book>
<author>Knorr, Stefan</author>
<title>Creepy Crawlies</title>
</book>
<book>
<author>Kress, Peter</author>
<title>Paradox Lost</title>
</book>
<book>
<author>Crichton, Michael</author>
<title>Jurassic Park</title>
</book>
<book>
<author>Orwell, George</author>
<title>1984</title>
</book>
<book>
<author>Martin, George</author>
<title>A Song of Ice And Fire</title>
</book>
</books>
我想在由两行五列组成的表格中显示这10本书。
我已经走了这么远:
<xsl:template match="books" mode="table">
<fo:table margin-left="auto" margin-right="auto">
<fo:table-body>
<fo:table-row table-layout="fixed">
<xsl:for-each select="skill">
<fo:table-cell border="1">
<fo:block font-weight="bold">
<xsl:value-of select="name"/>
</fo:block>
</fo:table-cell>
</xsl:for-each>
</fo:table-row>
</fo:table-body>
</fo:table>
</xsl:template>
但是,所有要做的就是将每个单元格放在同一行上。 我正在寻找一种方法来检查循环是否已经运行了一定次数(5或6),并在发生这种情况时插入新行,但是我不知道这是否可以在XSL中完成。
谁能指出我正确的方向?
先前的答案对于应该是(很简单)的事情来说是复杂的。 如此简单的事情不需要递归。
在XSL FO中,您不需要用行来构造表。 您可以使用属性“ ends-row”来指定要结束一行并开始新的一行。 您可以轻松地改编这个简单的示例,甚至传入“列数”(请参阅mod 5 ...,这意味着在每五分之一之后开始一个新行...更改为4或8或您想要的任何值)..您只需在此之外创建表的结构(fo:table和fo:table-body)。 像这样的模板一样,在表体内放入单元格就像子元素一样:
<xsl:template match="book">
<xsl:variable name="pos" select="position()"/>
<fo:table-cell>
<xsl:if test="not($pos mod 5)">
<xsl:attribute name="ends-row">true</xsl:attribute>
</xsl:if>
<fo:block>
<xsl:value-of select="author"/>
</fo:block>
</fo:table-cell>
</xsl:template>
因此,将其与您的数据一起放到一个简单的示例中...参见下文。 将XML格式化为每行五列。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.0">
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master margin-top="1in" margin-left="1in" margin-bottom="1in"
margin-right="1in" page-width="8in" page-height="11in" master-name="first">
<fo:region-body margin-top="0pt"/>
<fo:region-before extent="0pt"/>
<fo:region-after extent="0pt"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="first">
<fo:flow flow-name="xsl-region-body" font-size="12pt" font-family="Helvetica">
<xsl:apply-templates/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="books">
<fo:table>
<fo:table-body>
<xsl:apply-templates/>
</fo:table-body>
</fo:table>
</xsl:template>
<xsl:template match="book">
<xsl:variable name="pos" select="position()"/>
<fo:table-cell border="1pt solid black">
<xsl:if test="not($pos mod 5)">
<xsl:attribute name="ends-row">true</xsl:attribute>
</xsl:if>
<fo:block>
<xsl:value-of select="author"/>
</fo:block>
</fo:table-cell>
</xsl:template>
</xsl:stylesheet>
一种方法是使用两个递归模板:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
exclude-result-prefixes="ext">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<!-- set the number of columns you want globally -->
<xsl:param name="set-cols" select="'5'"/>
<xsl:template match="books">
<!-- count the needed rows -->
<xsl:variable name="set-row" select="ceiling(count(book) div $set-cols)"/>
<fo:table margin-left="auto" margin-right="auto">
<fo:table-body>
<xsl:call-template name="rows">
<xsl:with-param name="books">
<xsl:apply-templates/>
</xsl:with-param>
<xsl:with-param name="set-row" select="$set-row"/>
</xsl:call-template>
</fo:table-body>
</fo:table>
</xsl:template>
<!-- rows -->
<xsl:template name="rows">
<xsl:param name="books" select="''"/>
<xsl:param name="set-row" select="''"/>
<xsl:param name="count-rows" select="'0'"/>
<xsl:if test="$set-row > 0">
<fo:table-row table-layout="fixed">
<xsl:call-template name="cols">
<xsl:with-param name="books" select="$books"/>
<xsl:with-param name="count-rows" select="$count-rows"/>
</xsl:call-template>
</fo:table-row>
<xsl:call-template name="rows">
<xsl:with-param name="books" select="$books"/>
<xsl:with-param name="set-row" select="$set-row - 1"/>
<xsl:with-param name="count-rows" select="$count-rows + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- columns -->
<xsl:template name="cols">
<xsl:param name="books" select="''"/>
<xsl:param name="cols" select="$set-cols"/>
<xsl:param name="count-rows" select="''"/>
<xsl:param name="count-cols" select="'1'"/>
<xsl:if test="$cols > 0">
<fo:table-cell border="1">
<fo:block font-weight="bold">
<xsl:variable name="book" select="ext:node-set($books)//book[position() = ($count-rows * $set-cols + $count-cols)]"/>
<xsl:value-of select="$book/author"/>
</fo:block>
</fo:table-cell>
<xsl:call-template name="cols">
<xsl:with-param name="books" select="$books"/>
<xsl:with-param name="cols" select="$cols - 1"/>
<xsl:with-param name="count-rows" select="$count-rows"/>
<xsl:with-param name="count-cols" select="$count-cols + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
用你的输入
<books>
<book>
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
</book>
<book>
<author>Corets, Eva</author>
<title>Maeve Ascendant</title>
</book>
<!-- ... -->
</books>
你得到:
<fo:table margin-left="auto" margin-right="auto" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:table-body>
<fo:table-row table-layout="fixed">
<fo:table-cell border="1">
<fo:block font-weight="bold">Ralls, Kim</fo:block>
</fo:table-cell>
<fo:table-cell border="1">
<fo:block font-weight="bold">Corets, Eva</fo:block>
</fo:table-cell>
<fo:table-cell border="1">
<fo:block font-weight="bold">Corets, Eva</fo:block>
</fo:table-cell>
<fo:table-cell border="1">
<fo:block font-weight="bold">Randall, Cynthia</fo:block>
</fo:table-cell>
<fo:table-cell border="1">
<fo:block font-weight="bold">Thurman, Paula</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row table-layout="fixed">
<fo:table-cell border="1">
<fo:block font-weight="bold">Knorr, Stefan</fo:block>
</fo:table-cell>
<fo:table-cell border="1">
<fo:block font-weight="bold">Kress, Peter</fo:block>
</fo:table-cell>
<fo:table-cell border="1">
<fo:block font-weight="bold">Crichton, Michael</fo:block>
</fo:table-cell>
<fo:table-cell border="1">
<fo:block font-weight="bold">Orwell, George</fo:block>
</fo:table-cell>
<fo:table-cell border="1">
<fo:block font-weight="bold">Martin, George</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.