xsl:fo 内联换行和换行

xsl:fo inline line wrap and line break

我正在努力使用我的 xsl:fo (Apache Fop 1.1)。 我正在尝试生成一个包含内嵌图像和可能包含换行符的内嵌文本元素的块。

<fo:block>
    <fo:inline>First Line&#10;Second Line, Image: </fo:inline>
    <fo:inline>
        <fo:external-graphic scaling="non-uniform" content-height="scale-to-fit" content-width="4mm" height="4mm" src="data:image;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAABfCAIAAAB6Ck5uAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVHhe7cGBAAAAAMOg+VNf4QBVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCoAXMKAAFau+l4AAAAAElFTkSuQmCC"/>
    </fo:inline>
    <fo:inline> some more Text on Line 2&#10;3rd Line</fo:inline>
</fo:block>

我希望输出是

FirstLine
SecondLine, Image: || some more Text on Line 2
3rd Line

我得到的是:

FirstLine SecondLine, Image: || some more Text on Line 2 3rd Line

我已经玩了一段时间 fo:block 元素的以下属性 and/or fo:inline 元素给出了奇怪或意外的结果。

white-space-collapse="false" 
white-space-treatment="preserve" 
linefeed-treatment="preserve"

有什么建议吗?

编辑 1: 像这样将内联元素更改为块

<fo:block white-space-treatment="ignore">
    <fo:block white-space="pre">First Line&#xA;Second Line, Image: </fo:block>
    <fo:block>
        <fo:external-graphic scaling="non-uniform" content-height="scale-to-fit" content-width="4mm" height="4mm" src="data:image;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAABfCAIAAAB6Ck5uAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVHhe7cGBAAAAAMOg+VNf4QBVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCoAXMKAAFau+l4AAAAAElFTkSuQmCC"/>
    </fo:block>
    <fo:block white-space="pre"> some more Text on Line 2&#10;3rd Line</fo:block>
</fo:block>

为我提供了预期的元素换行,但为每个块生成了一个新行,这不是我要归档的内容。

刚刚在FOP 1536的评论中找到了答案。

现在我正在使用

linefeed-treatment="preserve"

在块元素上,我将文本内联中的所有空格替换为之前 xsl 中的一些 unicode 魔法:

replace(@text, ' ', '&#x00A0;&#x200B;') 

编辑 1: 更准确地说,这是我正在使用的 xsl 的相关部分:

<!DOCTYPE xsl:stylesheet [ 
    <!ENTITY nbsp "&#160;">
    <!ENTITY ZeroWidthSpace "&#x200B;"> 
]>

<fo:block linefeed-treatment="preserve">
    <fo:inline><xsl:value-of select="replace(@text, ' ', '&nbsp;&ZeroWidthSpace;')"/></fo:inline>
</fo:block>

通过这种方法,我得到了一个非常干净的缩进 xml,同时可以完全控制换行符和空格。

换行符可以作为换行符或数字字符实体(&#x000A;&#10;)出现在 FO 文档中;以下 FO 块是完全等效的:

<fo:block>Before the linefeed&#x000A;after the linefeed.</fo:block>

<fo:block>Before the linefeed
after the linefeed.</fo:block>

默认的换行处理包括:

  1. 将它们转换为普通空间;
  2. 将它们与其他相邻空间折叠

这解释了为什么您的初始输入会产生一个输出,其中所有内容片段都连续放置在同一行上。

使用 属性 linefeed-treatment="preserve" 两种形式的换行符都被保留,并且 line building process 将尊重它们(它们被称为强制换行符)。注意linefeed-treatment只适用于fo:block个元素;它对 fo:inline 元素没有影响。

您的 "edit 1" 块的换行符比您需要的多,因为“...第二行,图像:”,图像和 "some more Text on Line 2 ..." 在三个不同的 fo:block 元素,每个块生成自己的行。

解决方案 1:

获得所需输出的最简单方法可能是这个,其中单个 fo:block 保留了换行符(这只是您的原始输入,删除了不必要的 fo:inline 并将其放入所有内容都在同一行:

<fo:block linefeed-treatment="preserve">First Line&#xA;Second Line, Image: <fo:external-graphic scaling="non-uniform" content-height="scale-to-fit" content-width="4mm" height="4mm" src="data:image;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAABfCAIAAAB6Ck5uAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVHhe7cGBAAAAAMOg+VNf4QBVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCoAXMKAAFau+l4AAAAAElFTkSuQmCC"/> some more Text on Line 2&#10;3rd Line</fo:block>

请注意,您不能缩进此代码,因为额外的换行符也会出现在输出中!

解决方案 2:

第二种解决方案不涉及使用 linefeed-treatment 属性 并创建更易于阅读的代码,而是使用 空块 强制换行数:

<fo:block>
    First Line<fo:block/>Second Line, Image: 
    <fo:external-graphic scaling="non-uniform" content-height="scale-to-fit" content-width="4mm" height="4mm" src="data:image;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAABfCAIAAAB6Ck5uAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVHhe7cGBAAAAAMOg+VNf4QBVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCoAXMKAAFau+l4AAAAAElFTkSuQmCC"/> 
    some more Text on Line 2<fo:block/>3rd Line
</fo:block>

由于没有保留换行符,我们可以随意使用它们:

<fo:block>
    First Line
    <fo:block/>
    Second Line, Image: 
    <fo:external-graphic scaling="non-uniform" content-height="scale-to-fit" content-width="4mm" height="4mm" src="data:image;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAABfCAIAAAB6Ck5uAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVHhe7cGBAAAAAMOg+VNf4QBVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCoAXMKAAFau+l4AAAAAElFTkSuQmCC"/> 
    some more Text on Line 2
    <fo:block/>
    3rd Line
</fo:block>

空块对外部块的内容进行分区,而不会在输出中创建任何内容。