2013-08-21 20 views
0

如何使用xsl fo创建动态列数的表格。列数随每个输入文件而有所不同,但对于单个输入文件而言是固定的。在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性质。但无法了解如何使用它..

如果还有更好的方法,请让我来。

谢谢。

回答

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() &lt;= /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() &lt;= /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! 
+0

感谢您的回答。对不起,没有明确的问题。我对此很新,我以非常难看的方式解决了我的问题。我会尽力理解和实施这一点。对于学习的目的只是一个简单的问题,这是什么'>呢?和'name(。)'函数是什么。 –

+0

XPath地址'* [position()< =/root/ColNo]'首先处理所有子元素,然后只保留那些在子元素集中的位置小于或等于列号的人。因此,在你的数据的例子中,位置1,2和3. name()函数是一个展示函数,它展示了寻址节点的名字(或者当前节点,如果没有地址参数的话)。例如,你的输出数据有'prop1',我看到'prop1'的唯一地方就是元素的名字。 –