使用<xsl:value-of> </xsl:value-of>在XSL FO中生成的PDF中插入换行符

时间:2010-09-07 18:24:23

标签: xslt xsl-fo

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

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

我从其他地方搜索过,你可以在另一个<fo:block></fo:block>元素中使用<fo:block>在XSL FO中进行换行。因此,甚至在我使用XSL样式表解析XML之前,我将所有出现的<br/>替换为<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等上搜索这个都无济于事。任何建议或帮助将不胜感激。谢谢!

10 个答案:

答案 0 :(得分:38)

您也可以将<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。有关详细信息,请参阅Retain the &#xA; during xml marshalling

答案 1 :(得分:7)

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

为什么不用名为行分隔符的Unicode字符替换<br/>

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

请参阅https://en.wikipedia.org/wiki/Newline#Unicode

答案 2 :(得分:5)

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

答案 3 :(得分:5)

以下代码有效:

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

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

答案 4 :(得分:1)

试试这个:

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

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

答案 5 :(得分:0)

对于XSLT 1.0,我在GitHub上使用XSLT Line-Break Template

对于 XSL-FO ,它支持

  • 换行符
  • 行分隔符(与换行符对比)
  • 连续指针系列
  • 忽略指针重复(连续禁用指针系列)
  • 任何字符串作为插入分隔符或分隔符的指针(&#34; \ n&#34;是默认值)
  • 行分隔符&#39;高度
  • 当前字体大小的默认行分隔符高度。
  • 自动忽略&#34; \ r&#34;搜索休息地点时的字符。
  • 添加了对XSLT 2.0的支持,实现无缝迁移。
  • 别的......

对于XSLT 2.0及更高版本,请考虑使用

之类的方法
  • XSLT 2.0 xsl:analyze-string(RegEx)
  • XPath 2.0 tokenize + XSLT(RegEx)
  • 传递序列作为模板参数(XSLT 2.0)

答案 6 :(得分:0)

尝试使用换行处理=&#34;保留&#34;和\ n代替<br>换行。

<fo:block linefeed-treatment="preserve" >
 <xsl:value-of select="Description" />
</fo:block>

答案 7 :(得分:0)

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

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

我知道这不是最好的解决方案,但这是功能性的。

答案 8 :(得分: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>

注意:请注意空白

答案 9 :(得分:-2)

</fo:block>它本身不是<br/>的直接替代<br/>是一个html不成对的abberation,在xsl中没有直接的等价物:fo

</fo:block>只意味着阻止结束。如果你将它们分散在你的文本中,那么你将没有有效的xml,而你的xsl处理器将会出错。

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