使用XSL-FO在PDF中添加换行符?

时间:2011-07-20 15:07:59

标签: xml xslt xsl-fo

尝试使用XMLSpy创建基于XML和文件的PDF文件。

我正在尝试根据字段内容将字段拆分为两行。

例如,如果我的varialbe =“John Doe AKA Johnny D”,我想这样看:

John Doe

Johnny D

我的问题是即使网上的所有样本也无法使其正常工作。

这是我的代码:

      

     <xsl:value-of disable-output-escaping="yes" select="concat(substring-before(//MyField,'AKA'),$newline,substring-after(//MyField,'AKA'))" /> 
  </xsl:when>

所以基本上,eveytime我找到了“AKA”字符串,我想把这个字段分成两行。 所以我的代码,找到字符串,创建新变量,但仍然显示在一行。 我尝试使用各种技术创建一个带空行的变量,但仍然显示在一行中。

有什么想法吗?

2 个答案:

答案 0 :(得分:16)

有关使用十六进制实体引用和linefeed-treatment的信息,请参阅my answer here


修改

我从评论中获取了代码,并将其放在模板中的XSLT示例样式表中。我唯一改变的是:

  1. 我将您的newline变量更改为&#xA;
  2. 我将linefeed-treatment="preserve"添加到您的fo:block
  3. 使用虚拟XML文件和XSLT样式表,我制作了一个XSL-FO文档,当使用FOP渲染时,会在不同的行上生成“John Doe”和“Johnny D”。

    这是XML文件:

    <doc>
      <MyField>John Doe AKA Johnny D</MyField>
    </doc>
    

    这是XSLT样式表:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <xsl:output indent="yes"/>
      <xsl:strip-space elements="*"/>
    
      <xsl:template match="node()|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="/">
        <fo:root>
          <fo:layout-master-set>
            <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in">
              <fo:region-body margin="1in" margin-top="1.5in"/>
            </fo:simple-page-master>
          </fo:layout-master-set>
          <fo:page-sequence master-reference="my-page">
            <fo:flow flow-name="xsl-region-body">
              <xsl:apply-templates/>
            </fo:flow>
          </fo:page-sequence>
        </fo:root>
      </xsl:template>
    
      <xsl:template match="doc">
        <xsl:variable name="newline" select="'&#xA;'"/>        
        <xsl:variable name="MyVar">
          <xsl:choose>
            <xsl:when test="contains(//MyField,'AKA')">
              <xsl:value-of select="concat(substring-before(//MyField,'AKA'),$newline,substring-after(//MyField,'AKA'))"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="//MyField"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <fo:block linefeed-treatment="preserve">
          <xsl:value-of select="$MyVar"/>
        </fo:block>
      </xsl:template>
    
    </xsl:stylesheet>
    

    以下是生成的XSL-FO:

    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
       <fo:layout-master-set>
          <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in">
             <fo:region-body margin="1in" margin-top="1.5in"/>
          </fo:simple-page-master>
       </fo:layout-master-set>
       <fo:page-sequence master-reference="my-page">
          <fo:flow flow-name="xsl-region-body">
             <fo:root>
                <fo:layout-master-set>
                   <fo:simple-page-master page-height="11in" page-width="8.5in" master-name="my-page">
                      <fo:region-body margin-top="1.5in" margin="1in"/>
                   </fo:simple-page-master>
                </fo:layout-master-set>
                <fo:page-sequence master-reference="my-page">
                   <fo:flow flow-name="xsl-region-body">
                      <fo:block linefeed-treatment="preserve">John Doe 
     Johnny D</fo:block>
                   </fo:flow>
                </fo:page-sequence>
             </fo:root>
          </fo:flow>
       </fo:page-sequence>
    </fo:root>
    

    PDF是一个8.5“x 11”的页面,上面有这个:

    John Doe
    Johnny D
    

答案 1 :(得分:0)

@ daniel-haley的答案在源为:

时仍会产生一对名字
<doc>
    <MyField>John Doe AKA Johnny D</MyField>
    <MyField>Johnny D AKA John Doe</MyField>
    <MyField>John Smith</MyField>
</doc>

(在XPath 1.0中,将节点集转换为字符串只返回节点集中按文档顺序排在第一位的节点的字符串值。请参阅https://www.w3.org/TR/xpath/#function-string。)

下面的样式表会拆分包含“AKA”的任何文本节点。由于封闭的fo:block来自xsl:template MyField,因此此版本会生成空fo:block以导致换行。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output indent="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="/">
    <fo:root>
        <fo:layout-master-set>
            <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in">
                <fo:region-body margin="1in" margin-top="1.5in" />
            </fo:simple-page-master>
        </fo:layout-master-set>
        <fo:page-sequence master-reference="my-page">
            <fo:flow flow-name="xsl-region-body">
                <xsl:apply-templates />
            </fo:flow>
        </fo:page-sequence>
    </fo:root>
</xsl:template>

<!-- Could change to match on 'MyField/text()[contains(., ' AKA ')]'
     if necessary. -->
<xsl:template match="text()[contains(., ' AKA ')]">
    <xsl:value-of select="substring-before(., ' AKA ')" />
    <fo:block />
    <xsl:value-of select="substring-after(., ' AKA ')" />
</xsl:template>

<xsl:template match="MyField">
    <fo:block>
        <xsl:apply-templates />
    </fo:block>
</xsl:template>

</xsl:stylesheet>