如何使用xsl fo创建具有动态列数的表。列数因每个输入文件而异,但对于单个输入文件是固定的。
以下是xml示例
<root>
<ColNo>3</ColNo>
<Objects>
<object id="1">
<prop1 old="5" new="7">
<prop2 old="2" new="1">
<prop3 old="3" new="6">
</object>
</Objects>
</root>
我想要一张如下表格
Obj1
------------------------------------------
prop1 | prop2 | prop3
-------------------------------------------
old | new | old | new | old | new
-------------------------------------------
5 | 7 | 2 | 1 | 3 | 6
我遇到了number-columns-repeated
属性..但无法理解如何使用它..
如果有更好的方法,请告诉我。
感谢。
答案 0 :(得分:1)
你没有表明你已经尝试了多少,但我怀疑并不多,因为输入数据不是很好。而且您也没有说明如何表示多行数据,所以我通过修改添加其他信息的数据来猜测。
随后是完整的解决方案。它使用了两种可用的行填充技术,类似于我在教室中使用的插图(以及练习)。
当我通过符合要求的XSL-FO处理器运行下面的输出时,我按照你的要求概述了表格。
t:\ftemp>type table.xml
<root>
<ColNo>3</ColNo>
<Objects>
<object id="1">
<prop1 old="5" new="7"/>
<prop2 old="2" new="1"/>
<prop3 old="3" new="6"/>
<prop1 old="15" new="17"/>
<prop2 old="12" new="11"/>
<prop3 old="13" new="16"/>
</object>
</Objects>
</root>
t:\ftemp>call xslt table.xml table.xsl table.fo
t:\ftemp>type table.fo
<?xml version="1.0" encoding="utf-8"?>
<root xmlns="http://www.w3.org/1999/XSL/Format" font-family="Times" font-size="20pt">
<layout-master-set>
<simple-page-master master-name="frame" page-height="210mm" page-width="297mm" margin-top="1cm" margin-bottom="1cm" margin-left="1cm" margin-right="1cm">
<region-body region-name="frame-body"/>
</simple-page-master>
</layout-master-set>
<page-sequence master-reference="frame">
<flow flow-name="frame-body">
<block>Obj1</block>
<table border="solid 1pt" text-align="center">
<table-header>
<table-row>
<table-cell number-columns-spanned="2" border="solid 1pt">
<block>prop1</block>
</table-cell>
<table-cell number-columns-spanned="2" border="solid 1pt">
<block>prop2</block>
</table-cell>
<table-cell number-columns-spanned="2" border="solid 1pt">
<block>prop3</block>
</table-cell>
</table-row>
<table-row>
<table-cell border="solid 1pt">
<block>old</block>
</table-cell>
<table-cell border="solid 1pt">
<block>new</block>
</table-cell>
<table-cell border="solid 1pt">
<block>old</block>
</table-cell>
<table-cell border="solid 1pt">
<block>new</block>
</table-cell>
<table-cell border="solid 1pt">
<block>old</block>
</table-cell>
<table-cell border="solid 1pt">
<block>new</block>
</table-cell>
</table-row>
</table-header>
<table-body>
<table-cell border="solid 1pt">
<block>5</block>
</table-cell>
<table-cell border="solid 1pt">
<block>7</block>
</table-cell>
<table-cell border="solid 1pt">
<block>2</block>
</table-cell>
<table-cell border="solid 1pt">
<block>1</block>
</table-cell>
<table-cell border="solid 1pt">
<block>3</block>
</table-cell>
<table-cell border="solid 1pt" ends-row="true">
<block>6</block>
</table-cell>
<table-cell border="solid 1pt">
<block>15</block>
</table-cell>
<table-cell border="solid 1pt">
<block>17</block>
</table-cell>
<table-cell border="solid 1pt">
<block>12</block>
</table-cell>
<table-cell border="solid 1pt">
<block>11</block>
</table-cell>
<table-cell border="solid 1pt">
<block>13</block>
</table-cell>
<table-cell border="solid 1pt" ends-row="true">
<block>16</block>
</table-cell>
</table-body>
</table>
</flow>
</page-sequence>
</root>
t:\ftemp>type table.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/XSL/Format"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<root font-family="Times" font-size="20pt">
<layout-master-set>
<simple-page-master master-name="frame"
page-height="210mm" page-width="297mm"
margin-top="1cm" margin-bottom="1cm"
margin-left="1cm" margin-right="1cm">
<region-body region-name="frame-body"/>
</simple-page-master>
</layout-master-set>
<page-sequence master-reference="frame">
<flow flow-name="frame-body">
<!--reposition to the top of table data-->
<xsl:for-each select="root/Objects/object">
<block>Obj<xsl:value-of select="@id"/></block>
<table border="solid 1pt" text-align="center">
<table-header>
<!--header rows - use row-based row-grouping strategy-->
<table-row>
<xsl:for-each select="*[position() <= /root/ColNo]">
<table-cell number-columns-spanned="2" border="solid 1pt">
<block><xsl:value-of select="name(.)"/></block>
</table-cell>
</xsl:for-each>
</table-row>
<table-row>
<xsl:for-each select="*[position() <= /root/ColNo]">
<table-cell border="solid 1pt"><block>old</block></table-cell>
<table-cell border="solid 1pt"><block>new</block></table-cell>
</xsl:for-each>
</table-row>
</table-header>
<table-body>
<!--body rows - use cell-based row-grouping strategy-->
<xsl:apply-templates select="*"/>
</table-body>
</table>
</xsl:for-each>
</flow>
</page-sequence>
</root>
</xsl:template>
<xsl:template match="object/*">
<table-cell border="solid 1pt">
<block><xsl:value-of select="@old"/></block>
</table-cell>
<table-cell border="solid 1pt">
<xsl:if test="position() mod /root/ColNo = 0">
<!--every time the last item of a row is encountered, signal end-->
<xsl:attribute name="ends-row">true</xsl:attribute>
</xsl:if>
<block><xsl:value-of select="@new"/></block>
</table-cell>
</xsl:template>
</xsl:stylesheet>
t:\ftemp>start table.fo
t:\ftemp>rem Done!