如何在函数中写 <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>
...
我必须在 <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”的有效子项!
但是当我在没有
<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>
...