Xml XSLT&;XSL-FO:创建具有多行的表?

Xml XSLT&;XSL-FO:创建具有多行的表?,xml,xslt,xsl-fo,Xml,Xslt,Xsl Fo,我是XSLT的新手,我遇到了一个问题,我有一个元素的子元素数量未知,我需要在一个表中显示这些子元素,以便有5-6列可用于显示信息 如果给我一个如下所示的XML文件: <books> <book> <author>Ralls, Kim</author> <title>Midnight Rain</title> </book> <book>

我是XSLT的新手,我遇到了一个问题,我有一个元素的子元素数量未知,我需要在一个表中显示这些子元素,以便有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>

拉尔斯,金
夜雨
科雷茨,伊娃
梅夫上升
科雷茨,伊娃
奥伯伦的遗产
兰德尔,辛西娅
情人鸟
瑟曼,保拉
水花四溅
克诺尔,斯特凡
令人毛骨悚然的爬虫
克雷斯,彼得
悖论丢失
克莱顿,迈克尔
侏罗纪公园
奥威尔,乔治
1984
马丁,乔治
冰与火之歌
我想在一个由两行五列组成的表格中显示这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: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 &gt; 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 &gt; 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>

用yout输入

<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>

拉尔斯,金
科雷茨,伊娃
科雷茨,伊娃
兰德尔,辛西娅
瑟曼,保拉
克诺尔,斯特凡
克雷斯,彼得
克莱顿,迈克尔
奥威尔,乔治
马丁,乔治

一种方法是使用两个递归模板:

<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 &gt; 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 &gt; 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>

用yout输入

<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>

拉尔斯,金
科雷茨,伊娃
科雷茨,伊娃
兰德尔,辛西娅
瑟曼,保拉
克诺尔,斯特凡
克雷斯,彼得
克莱顿,迈克尔
奥威尔,乔治
马丁,乔治

前面的答案对于应该(而且是)简单的东西来说是复杂的。这种简单的事情不需要递归

在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>

真的

对于w来说,前面的答案非常复杂