XSL-FO 高级技术7

来源:互联网 发布:手机分辨率修改软件 编辑:程序博客网 时间:2024/04/29 02:48
概述 第 1 页(共5 页)

XSL-FO 常用于将 HTML 文档转换成 PDF。要做到这一点,使用 XSLT 将 HTML 元素转换成格式化对象,格式化对象是用 XSL-FO 显示的文档的基本构件。然后,再将格式化对象转换成 PDF。本章概述如何将 HTML 文档转换成相应的格式化对象。然后,下一章(使转换技术工作)将使用这些模板自动创建目录和一组书签,最后创建一个样本 PDF 文档。

本章只包含少数几个 HTML 元素来演示基本过程。对于所有我所见到在 PDF 转换中起作用的 HTML 元素,我已经整理了一本更完整的指南,说明它们的格式化对象中的等价对象和 XSLT 转换模板。一旦您学习了本教程中的技术,就可以参考该参考指南(请参阅参考资料)来对具有更多元素的 HTML 文档构建转换模板。

简要说明:本章示例中几乎所有的 XSLT 模板都包含这个元素:

<xsl:apply-templates select="*|text()"/>

该元素告诉 XSLT 处理器获取当前元素的所有文本及其子元素,并转换它们。不管 HTML 元素之间如何嵌套,这一递归技术确保处理所有这些元素。


<body>文档主体 第 2 页(共5 页)

<body> 元素的 XSL-FO 等价元素是 <fo:flow flow-name="xsl-region-body"> 元素。为了保持 HTML 文档和 XSLT 样式表之间的对称,这里的示例将该处理用于 <body> 元素来生成相应的 XSL-FO 元素。对于示例文档,<fo:flow flow-name="xsl-region-body"> 元素包含以下六项:

  • 文档标题(<head> 内的 HTML title 元素)
  • 欢迎消息 developerWorks loves you!
  • developerWorks URL
  • 目录
  • 文档中的所有内容
  • 用于标识文档最后一页的 id

很明显,包括了其中的大部分项,使得文档有预期的布局。您可以更改 XSLT 模板来创建不同布局(例如,或许您喜欢标题页),或者可以使用多个样式表以多种格式显示相同信息。下面是完整的模板:

<xsl:template match="body">  <fo:flow flow-name="xsl-region-body">    <!-- Item 1 -->    <xsl:apply-templates select="/html/head/title"/>    <!-- Item 2 -->    <fo:block space-after="12pt" line-height="17pt"       font-size="14pt" text-align="center">      developerWorks loves you!    </fo:block>    <!-- Item 3 -->    <fo:block space-after="24pt" line-height="17pt"       font-size="14pt" text-align="center" font-weight="bold"       font-family="monospace">      ibm.com/developerWorks    </fo:block>    <!-- Item 4 -->    <xsl:call-template name="toc"/>    <!-- Item 5 -->    <xsl:apply-templates select="*|text()"/>    <!-- Item 6 -->    <fo:block id="TheVeryLastPage" font-size="0pt"      line-height="0pt" space-after="0pt"/>  </fo:flow></xsl:template>

<h1><h6> 标题 第 3 页(共5 页)

转换标题标记相对比较简单;将每个标记放到 <fo:block> 元素中,并根据标题级别更改字体、字体大小和其它属性。要使顶层标题真正突出,示例布局在 <h1> 文本之前放置了分页符和一条水平线。下面是所用的格式化选项:

HTML 标记 字体大小 线高 后面的空格 其它 <h1> 28pt 32pt 22pt 在文本的前面添加分页符和一条水平线 <h2> 24pt 28pt 18pt 无 <h3> 21pt 24pt 14pt 无 <h4> 18pt 21pt 12pt 无 <h5> 16pt 19pt 12pt 文本加下划线 <h6> 14pt 17pt 12pt 文本加下划线用斜体字表示

下面是一些标题元素:

<h1>Sample text from Henry Fielding's <cite>Tom Jones</cite></h1><h2><b>Book I.</b>  Containing as Much of the Birth of the Foundling   as Is Necessary or Proper to Acquaint the Reader with in the   Beginning of This History</h2><h3><b>Chapter VII.</b>  Containing Such Grave Matter, That the Reader  Cannot Laugh Once Through the Whole Chapter, Unless Peradventure He   Should Laugh at the Author</h3>

这些元素被转换成下列格式化对象:

<fo:block break-before="page">  <fo:leader leader-pattern="rule"/></fo:block><fo:block font-family="serif" space-after="22pt" keep-with-next="always"     line-height="32pt" font-size="28pt" id="tomjones">  Sample text from Henry Fielding's     <fo:inline font-style="italic">Tom Jones</fo:inline></fo:block><fo:block font-family="serif" space-after="18pt" keep-with-next="always"     line-height="28pt" font-size="24pt" id="N10017">  <fo:inline font-weight="bold">Book I.</fo:inline>    Containing as Much of the Birth of the Foundling   as Is Necessary or Proper to Acquaint the Reader with in the   Beginning of This History</fo:block><fo:block font-family="serif" space-after="14pt" keep-with-next="always"     line-height="24pt" font-size="21pt" id="N1001C">  <fo:inline font-weight="bold">Chapter VII.</fo:inline>    Containing Such Grave Matter, That the Reader  Cannot Laugh Once Through the Whole Chapter, Unless Peradventure He   Should Laugh at the Author</fo:block>

<h1><h6> 标题 — 模板 第 4 页(共5 页)

<h1> 元素的文本之前插入的分页符会使将已命名的锚与 <h1> 元素一起使用变得复杂。出于这个原因,<h1> 元素的 XSLT 模板检查前一个元素,以了解它是不是已命名的锚。下面是 <h1><h6> 元素的模板:

<xsl:template match="h1">  <fo:block break-before="page">    <fo:leader leader-pattern="rule"/>  </fo:block>   <fo:block font-size="28pt" line-height="32pt"      keep-with-next="always"      space-after="22pt" font-family="serif">    <xsl:attribute name="id">      <xsl:choose>        <xsl:when test="@id">          <xsl:value-of select="@id"/>        </xsl:when>        <xsl:when test="name(preceding-sibling::*[1]) = 'a' and                         preceding-sibling::*[1][@name]">          <xsl:value-of select="preceding-sibling::*[1]/@name"/>        </xsl:when>        <xsl:otherwise>          <xsl:value-of select="generate-id()"/>        </xsl:otherwise>      </xsl:choose>    </xsl:attribute>    <xsl:apply-templates select="*|text()"/>  </fo:block></xsl:template><xsl:template match="h6">  <fo:block font-size="14pt" line-height="17pt"      keep-with-next="always" space-after="12pt"      font-family="serif" font-style="italic"      text-decoration="underline">    <xsl:attribute name="id">      <xsl:choose>        <xsl:when test="@id">          <xsl:value-of select="@id"/>        </xsl:when>        <xsl:otherwise>          <xsl:value-of select="generate-id()"/>        </xsl:otherwise>      </xsl:choose>    </xsl:attribute>    <xsl:apply-templates select="*|text()"/>  </fo:block></xsl:template>

最后注意一点:因为标题用于书签和目录,并且是有用的链接点,所以最好确保每个标题都有一个 id。如果给定的标题元素已经有一个 id 属性,则使用它;否则,使用 XSLT 的 generate-id() 函数创建一个标识:

<xsl:attribute name="id">  <xsl:choose>    <xsl:when test="@id">      <xsl:value-of select="@id"/>    </xsl:when>    <xsl:otherwise>      <xsl:value-of select="generate-id()"/>    </xsl:otherwise>  </xsl:choose></xsl:attribute>

<hr>水平的直线 第 5 页(共5 页)

有一个特殊的 XSL-FO 元素 <fo:leader>,它是为处理水平的直线而设计的。下面是一些 HTML 标记:

<p>Here's a short paragraph.</p><hr/><p>Here's another paragraph, following a horizontal rule.</p>

显示该内容的 XSL-FO 标记应该类似于:

<fo:block>  Here's a short paragraph.</fo:block><fo:block>  <fo:leader leader-pattern="rule"/></fo:block><fo:block>  Here's another paragraph, following a horizontal rule.</fo:block>

处理 <hr> 元素的 XSLT 模板非常简单:

<xsl:template match="hr">  <fo:block>    <fo:leader leader-pattern="rule"/>  </fo:block></xsl:template>

最后注意一点:leader-pattern 属性还支持 dots(通常在目录中使用)的值和 space(它创建空白区域)的值。