如何在xml节点之后添加换行符,以便FOP识别空格?

时间:2014-02-25 12:00:59

标签: xml xslt apache-fop

我们正在使用带有XSLT的Apache FOP 1.1来生成用于打印的PDF。我们的软件正确创建XML,并将其直接传递给FOP转换器。我们没有保存任何文件,所以使用变换器属性来缩进XML对这里没有帮助。

基本上我们的XML生成器创建一个如下所示的XML文档:

<document><list><item>1</item><item>2</item><item>3</item></list></document>

并且我们的XSLT有一点占用item节点的每个list子节点,并且假设将它们打印出来,中间有空格。像这样:

<!DOCTYPE xsl:stylesheet [
     <!ENTITY nbsp '<xsl:text xmlns:xsl="http://www.w3.org/1999/XSL/Transform">&#160;</xsl:text>'>
]>
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" /> 
 <xsl:template match="list">
     <fo:inline>Items:&nbsp;</fo:inline>
     <xsl:for-each select="item">
          <xsl:value-of select="./text()"/>&nbsp;
     </xsl:for-each>
</xsl:template>

在XSLT文档的最顶端,我已经告诉它实体&nbsp;是什么,这应该不是问题。问题是,在生成文件时,项目而不是显示为Items: 1 2 3的项目显示为Items: 123。我能找到的唯一解决问题的方法就是当我生成XML然后将其转换为String时,文档现在看起来像这样:

<document>
     <list>
          <item>1</item>
          <item>2</item>
          <item>3</item>
     </list>
</document>

XSLT是否正确输出列表。所以我想要做的是通过DOM在列表中的每个项目之后添加换行节点,而不必先将其转换并将其保存到文件中。这可能吗?

更新<!/强> 我想向所有帮助过的人道歉。给出了正确的答案,但由于我正在处理模板的错误部分,我没有看到修正工作。是的,因为您注意到我没有发布整个模板,这是由于其性质和来源。几年前,我启动了模板并使其工作,后来另一位开发人员对模板进行了更改,并停止使用我最初在工作的子模板。因此,当我回到它时,我当然正在我认为它工作的地方工作,并且想知道为什么我没有看到这些变化。

感谢您的支持。这个问题已经解决了。

2 个答案:

答案 0 :(得分:2)

如果我改造,你可以发布更多你的FO样式表吗?

<document><list><item>1</item><item>2</item><item>3</item></list></document>

使用:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fo="http://www.w3.org/1999/XSL/Format"
exclude-result-prefixes="xs"
version="1.0">

<xsl:template match="document">
    <fo:root>
        <fo:layout-master-set>
            <fo:simple-page-master master-name="test">
                <fo:region-body region-name="region"/>
            </fo:simple-page-master>
        </fo:layout-master-set>
        <fo:page-sequence master-reference="test">
            <fo:flow flow-name="region">
                <fo:block><xsl:apply-templates select="list"/></fo:block>
            </fo:flow>
        </fo:page-sequence>
    </fo:root>      
</xsl:template>

<xsl:template match="list">
    <fo:inline>Items:<xsl:text> </xsl:text></fo:inline>
    <xsl:for-each select="item">
        <xsl:value-of select="./text()"/><xsl:text> </xsl:text>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

我得到的PDF看起来像这样:

result pdf

答案 1 :(得分:1)

您的实体声明有点混乱。其中有一个名称空间声明,&#160不以分号结尾。

不要在xsl:text元素中包含文本甚至单个字符,也不要输出它们。这可确保它们正确序列化。换句话说,改变

&nbsp;

<xsl:text>&nbsp;</xsl:text>

我还简化了您的实体声明。在实体声明中包含XSLT元素和名称空间声明是没有意义的。

无论如何,您在xsl:stylesheet上声明了XSLT名称空间,并且无需重新声明它。 xsl:text元素应放在实际代码中,而不是放在实体声明中。

<强>输入

<document><list><item>1</item><item>2</item><item>3</item></list></document>

<强>样式表

<!DOCTYPE xsl:stylesheet [
     <!ENTITY nbsp '&#160;'>
]>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" /> 

<xsl:template match="list">
     <fo:inline>
     <xsl:text>Items:&nbsp;</xsl:text>
     <xsl:for-each select="item">
          <xsl:value-of select="."/>
          <xsl:text>&nbsp;</xsl:text>
     </xsl:for-each>
     </fo:inline>
</xsl:template>

</xsl:stylesheet>

<强>输出

<?xml version="1.0" encoding="utf-8"?>
<fo:inline xmlns:fo="http://www.w3.org/1999/XSL/Format">Items: 1 2 3 </fo:inline>