如何在函数中写 <fo:table> 的一部分

How to wirte a part of <fo:table> in a function

我必须在 <fo:table-body> 中创建许多 <fo:table-row>。我认为如果我多次(可能 50 次)编写将近 5 行代码来创建行,这并不好。

像这样:

<fo:table-body>
<fo:table-row>
   <fo:table-cell padding-bottom="6pt">
       <fo:value-of select="row1"/>
   </fo:table-cell>
</fo:table-row>
<fo:table-row>
   <fo:table-cell padding-bottom="6pt">
       <fo:value-of select="row2"/>
   </fo:table-cell>
</fo:table-row>
<fo:table-row>
   <fo:table-cell padding-bottom="6pt">
       <fo:value-of select="row3"/>
   </fo:table-cell>
</fo:table-row>
....
</fo:table-body>

我尝试编写一个函数来为我写入 。而且我每次都必须调用函数并传递一个参数。

<xsl:function name="fn:createRow">
    <xsl:param name="string1"/>
    
    <fo:table-row>
       <fo:table-cell padding-bottom="6pt">
           <fo:value-of select="$string1"/>
       </fo:table-cell>
    </fo:table-row>
               
  </xsl:function>

现在我的 XSLT 看起来像这样。

<fo:table-body>
    <fo:block>
           <fo:value-of select="fn:createRow('row1')"/>
           <fo:value-of select="fn:createRow('row2')"/>
   </fo:block>
</fo:table-body>

但我得到错误:

“fo:block”不是“fo:table-body”的有效子项!

但是当我在没有 的情况下工作时,我在 PDF 中什么也得不到:

<fo:table-body>
       <fo:value-of select="fn:createRow('row1')"/>
       <fo:value-of select="fn:createRow('row2')"/>
</fo:table-body>

有机会做吗?

谢谢!

我认为你想要 <xsl:value-of select="$string1"/> 而不是 <fo:value-of select="$string1"/>。我还会检查 fo:table-cell 是否允许内联内容,可能需要将 fo:block 容器放入具有 xsl:value-of 子元素的单元格中。

此外,对于函数调用,不要使用<fo:value-of select="fn:createRow('row1')"/>,而是使用<xsl:sequence select="fn:createRow('row1')"/>

此外,fn是保留前缀,供您自己的函数声明和使用您自己的命名空间(例如xmlns:mf="http://example.com/mf"<xsl:function name="mf:createRow" ...>...</xsl:function>,然后使用<xsl:sequence select="mf:createRow('row1')"/>

所以函数的一个例子是

<xsl:function name="mf:createRow">
    <xsl:param name="input"/>
    
    <fo:table-row>
       <fo:table-cell padding-bottom="6pt">
           <fo:block>
             <xsl:value-of select="$input"/>
           </fo:block>
       </fo:table-cell>
    </fo:table-row>
               
</xsl:function>

你可以这样称呼它

  <fo:table-body>
    <xsl:sequence select="(1 to 3) ! ('Row ' || . ) ! mf:createRow(.)"/>
  </fo:table-body>

fo:table-cell 可以包含一个或多个 block-level 个 FO,包括 fo:block。 (参见 https://www.w3.org/TR/xsl11/#fo_table-cell

您没有显示 XML,但如果所有 row* 元素都包含在一个元素中,那么在该元素的模板中,您可以执行如下操作:

<fo:table>
  <fo:table-body>
    <xsl:for-each select="*">
      <fo:table-row>
        <fo:table-cell padding-bottom="6pt">
          <fo:block>
            <!-- The row* element is the current element here. -->
            <xsl:apply-templates />
          </fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:for-each>
  </fo:table-body>
</fo:table>

或者,您可以为所有 row* 元素制作一个模板:

<xsl:template match="*[starts-with(local-name(), 'row')]">
  <fo:table-row>
  ...

(从这个距离来看,还不清楚为什么行元素需要单独的元素名称。)


当您知道要格式化的元素的名称时,您可以执行以下操作:

<xsl:apply-templates select="row1, row2, row3" />

和:

<xsl:template match="row1 | row2 | row3">
  <fo:table-row>
  ...