使用XSL定义特定元素的缩进

时间:2014-01-17 16:59:54

标签: xslt xslt-2.0

我正在编写一个XSL,它创建一个包含一些文学参考的XSL-FO。我遇到的一个问题是正确处理引用中的三重破折号。当同一作者在两个连续引用中重复时,使用三重em破折号代替第二个引用中的作者姓名。应该关闭em破折号。

我发现实现这一目的的XSL-FO方法是使用fo:字符代替em破折号,字母间距为负。不幸的是,当我输出FO时,每个fo:character元素都放在它自己的行上,我认为FO处理器将其解释为空格。所以我的冲刺最终会间隔开来。如果我进入FO并将它们放在同一条线上,它们看起来应该是这样。

我的问题的简单解决方案是将xsl:output的indent属性设置为no。但是,我的FO文件很长,这使得它无法读取。我想知道是否有任何其他方法强制特定元素的缩进规则。 (我对在XSL-FO中处理此问题的另一种方法持开放态度,但我理解这应该是一个不同的SO问题。)

这是添加fo:character标签的模板。

<xsl:template match="ref/text()[matches(., '^———.')]">
    <fo:character character="—" letter-spacing="-.2em"/><fo:character character="—" letter-spacing="-.2em"/><fo:character character="—" letter-spacing="-.2em"/><xsl:copy-of select="substring-after(., '———')"/>
</xsl:template>

示例简短XML:

<document>
    <ref>———. <i>Hamlet</i>. Ed. Harold Jenkins. London: Methuen, 1982. Print.</ref>
</document>

我用indent =“是”得到的输出的片段:

<fo:block start-indent="11pt"
        text-indent="-11pt">
    <fo:character character="—" letter-spacing="-.2em"/>
    <fo:character character="—" letter-spacing="-.2em"/>
    <fo:character character="—" letter-spacing="-.2em"/>. <fo:inline font-style="italic">Hamlet</fo:inline>. Ed. Harold Jenkins. London: Methuen, 1982. Print.</fo:block>

我正在使用XSL 2.0和Saxon-HE。条件缩进是可能的,还是我应该找到另一种解决方案?

2 个答案:

答案 0 :(得分:2)

为了获得正确的输出,您不需要牺牲可读性。

尽量不要在全球范围内改变对换行的处理(即全面地,通过indent="no"),但在fo:block的水平上:

<fo:block start-indent="11pt"
        text-indent="-11pt"
        linefeed-treatment="ignore">
    <fo:character character="—" letter-spacing="-.2em"/>
    <fo:character character="—" letter-spacing="-.2em"/>
    <fo:character character="—" letter-spacing="-.2em"/>. <fo:inline font-style="italic">Hamlet</fo:inline>. Ed. Harold Jenkins. London: Methuen, 1982. Print</fo:block>

这应该会导致忽略此块中的任何换行符。当然,这意味着您必须识别应包含“ - ”字符的块并添加此属性。

有关规范的相关部分,请参阅:http://www.w3.org/TR/xsl/#linefeed-treatment。此外,还有一些属性可以指定您的FO处理器如何处理空白,即whitespace-treatmentwhite-space-collapsewhite-space(总结了许多其他属性)。

您的案例可能涉及上述任何属性。确切的工作方式取决于您的FO处理器和版本。

获得技术能力概述的良好资源可能还有:http://www.schemacentral.com/sc/fo11/a-linefeed-treatment-1.html

答案 1 :(得分:1)

我同情你的FO输出非常长的事实,并且没有缩进它使得它难以阅读。在生成TeX代码时,我有时会遇到类似的问题:为了调试目的,我需要使它具有人类可读性,但有时会改变生成代码的语义。

然而,这里存在一个根本性的冲突:FO认为输入文档中的文本节点(包括空格)很重要,实际上它必须是为了正常工作。因此,如果您告诉您的FO生成器样式表插入空格(通过缩进=“是”),它将被视为重要的。

您已经知道这一点,并且正在询问如何有选择地避免缩进。我认为撒克逊人没有办法做到这一点。但我会建议其他几个角度:

  1. 如果使用<fo:block>生成xml:space="default"会怎样? FO处理器没有义务尊重该声明,但可能值得一试。

  2. 您可以分叉您的进程以生成两个输出,一个是人类可读的(使用indent="yes"生成),另一个是供FO处理器使用的输出(无缩进生成)。

  3. 您可以在样式表中关闭内置缩进(indent="yes"),然后“滚动自己的”完全自定义缩进过程。后者可能是同一个XSLT样式表的一部分;或者它可以是一个完全独立的工具,无论哪个满足您的需求。

相关问题