30

我正在使用 XSL FO 生成一个包含信息表的 PDF 文件。这些列之一是“描述”列。我填充这些描述字段之一的字符串示例如下:

This is an example Description.<br/>List item 1<br/>List item 2<br/>List item 3<br/>List item 4

在与此描述对应的表格单元格内,我希望输出显示如下:

This is an example Description.
List item 1
List item 2
List item 3
List item 4

我从其他地方的搜索中了解到,您可以在 XSL FO 中使用<fo:block></fo:block>另一个<fo:block>元素中的 an 进行换行。因此,甚至在我用我的 XSL 样式表解析 XML 之前,我都会替换所有出现的<br/>with <fo:block/>,因此字符串的文字值现在看起来像:

This is an example Description.<fo:block/>List item 1<fo:block/>List item 2<fo:block/>List item 3<fo:block/>List item 4

当我使用的描述字符串是使用 获取时,就会出现问题<xsl:value-of>,示例如下:

<fo:block>
    <xsl:value-of select="descriptionStr"/>
</fo:block>

在这种情况下,输出到我的 PDF 文档的值是文字值,因此它看起来与前面的示例完全一样,其中包含所有<fo:block/>文字。我尝试<fo:block/>在另一个字符串的中间手动硬编码,它显示正确。例如,如果我在样式表中写:

<fo:block>Te<fo:block/>st</fo:block>

它将正确显示为:

Te
st

但是,当 位于语句<fo:block/>的值内时,这似乎不会发生。<xsl:value-of select=""/>我试过在 SO 和 Google 等上搜索这个,但无济于事。任何建议或帮助将不胜感激。谢谢!

4

11 回答 11

46

您还可以替换<br/>&#xA;并添加一个linefeed-treatment="preserve"属性到您的<fo:block>.

就像是:

<fo:block linefeed-treatment="preserve">This is an example Description.&#xA;List item 1&#xA;List item 2&#xA;List item 3&#xA;List item 4</fo:block>

编辑

一些用户可能需要使用\n而不是&#xA;依赖于他们创建 XML 的方式。请参阅保留 在 xml 编组期间了解更多详细信息。

于 2010-09-08T03:32:43.350 回答
11

这对我有帮助,应该是最简单的解决方案(使用 Apache FOP 1.1):

为什么不用称为line separator<br/>的 Unicode 字符替换你的。

   <xsl:template match="br">
      <xsl:value-of select="'&#x2028;'"/>
   </xsl:template>

https://en.wikipedia.org/wiki/Newline#Unicode

于 2015-12-15T12:14:36.997 回答
6

以下代码有效:

<fo:block white-space-collapse="false" 
    white-space-treatment="preserve" 
    font-size="0pt" line-height="15px">.</fo:block>

它使 xsl 处理器认为该块包含一行文本,实际上它的字体大小为 0pt。您可以通过提供自己的值来自定义行高。

于 2013-08-30T04:12:51.347 回答
5

您不应该使用xsl:value-of指令,xsl:apply-templates而是:对于文本节点的内置规则只会输出它们的字符串值,对于空br元素,您可以声明一个规则匹配descriptionStr/brdescriptionStr//br(取决于您的输入)以转换为 empty fo:block

于 2010-09-07T19:22:32.507 回答
3

生成包含转义 XML 标记的字符串很少是正确的答案,但如果这是您必须使用的,那么对于这样的输入:

<Description><![CDATA[This is an example Description.<br/>List item 1<br/>List item 2<br/>List item 3<br/>List item 4]]></Description>

如果您使用的是 XSLT 2.0,则可以使用xsl:analyze-string来获取您最初想要的空白fo:block

<xsl:template match="Description">
  <fo:block>
    <xsl:analyze-string select="." regex="&lt;br/>">
      <xsl:matching-substring>
        <fo:block />
      </xsl:matching-substring>
      <xsl:non-matching-substring>
        <xsl:value-of select="." />
      </xsl:non-matching-substring>
    </xsl:analyze-string>
  </fo:block>
</xsl:template>

但如果您使用的是 XSLT 2.0,您可以更简洁地linefeed-treatment="preserve"按照@Daniel Haley 使用并replace()用于插入换行符:

<xsl:template match="Description">
  <fo:block linefeed-treatment="preserve">
    <xsl:value-of select="replace(., '&lt;br/>', '&#xA;')" />
  </fo:block>
</xsl:template>

如果您使用的是 XSLT 1.0,您可以通过字符串递归:

<xsl:template match="Description">
  <fo:block linefeed-treatment="preserve">
    <xsl:call-template name="replace-br" />
  </fo:block>
</xsl:template>

<xsl:template name="replace-br">
  <xsl:param name="text" select="." />

  <xsl:choose>
    <xsl:when test="not(contains($text, '&lt;br/>'))">
      <xsl:value-of select="$text" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="substring-before($text, '&lt;br/>')"/>
      <xsl:text>&#xA;</xsl:text> <!-- or <fo:block /> -->
      <xsl:call-template name="replace-br">
        <xsl:with-param name="text" select="substring-after($text, '&lt;br/>')"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
于 2016-08-13T14:54:28.123 回答
1

试试这个:

<fo:block><fo:inline color="transparent">x</fo:inline></fo:block>

此代码添加了一个包含透明文本的块,使其看起来像一个新行。

于 2013-08-29T09:23:20.510 回答
1

尝试使用 linefeed-treatment="preserve" 和 \n 而不是<br>换行。

<fo:block linefeed-treatment="preserve" >
 <xsl:value-of select="Description" />
</fo:block>
于 2016-07-19T03:43:06.660 回答
0

对于 XSLT 1.0,我在 GitHub 上使用我的XSLT 换行模板。

对于XSL-FO,它支持

  • 换行符
  • 行分隔符(与换行符)
  • 指针系列连续
  • 忽略指针重复(连续禁用指针系列)
  • 任何字符串作为插入分隔符或分隔符的指针(默认为“\n”)
  • 行分隔符的高度
  • 当前字体大小的默认行分隔符高度。
  • 搜索中断位置时自动忽略“\r”字符。
  • 添加了对 XSLT 2.0 的支持以实现无缝迁移。
  • 别的东西……

对于 XSLT 2.0 及更高版本,请考虑使用类似的方法

  • XSLT 2.0 xsl:分析字符串 (RegEx)
  • XPath 2.0 标记化 + XSLT (RegEx)
  • 将序列作为模板参数传递 (XSLT 2.0)
  • 等等
于 2016-01-20T13:41:16.330 回答
0

如果我需要更多或更少的空间,我通常使用可以更改高度的空块:

<fo:block padding-top="5mm" />

我知道这不是最好看的解决方案,但它很实用。

于 2018-12-27T09:03:42.387 回答
0

我有一个看起来像这样的文本块

<fo:table-cell display-align="right">
<fo:block font-size="40pt" text-align="right">
    <xsl:text> Text 1 </xsl:text>
    <fo:block> </fo:block>
    <xsl:text> Text2 </xsl:text>
    <fo:block> </fo:block>
    <xsl:text> Text 3</xsl:text>
</fo:block>

注意:注意空

于 2019-02-20T10:57:18.267 回答
-2

</fo:block>就其本身而言,不能直接替代<br/> <br/>在 xsl:fo 中没有直接等效项的 html 未配对缩写词

</fo:block> 只是意味着块的结束。如果您将它们分散在您的文本中,您将没有有效的 xml,并且您的 xsl 处理器会出现错误。

对于您想要的换行格式,每个块将出现在新行上。每行都需要一个<fo:block>起始块和</fo:block>结束块对。

于 2012-04-03T21:52:00.050 回答